<template
  ><!---->
  <div
    id="ctfDetail"
    class="sceneDetail"
    v-if="
      ((isDistributed == 0 || (isDistributed == 1 && isMainRange == 1)) &&
        environInfo &&
        drillDetail.id) ||
        (isDistributed == 1 && isMainRange == 0 && drillDetail.id)
    "
  >
    <!--<Row :style="{'margin-bottom':'10px'}">
			场景:
			<Select filterable v-model="drill" style="width:200px" @on-change="getCurDrill">
		        <Option v-for="item in drillSecensList" :value="JSON.stringify(item)" :key="item.drillitemid">{{ item.drillitemname }}</Option>
		   </Select>
		   <span v-if="projectId">
		   <span>演练模式</span> <Tag color="blue">{{ project.drillmode | filterMode}}</Tag>
		   <span>类型</span> <Tag color="blue">{{ project.type | typeFilter}}</Tag>
		   </span>
	    </Row>-->
    <!--<Breadcrumb style="margin-bottom: 22px">
          <BreadcrumbItem :to="backObj">演练列表</BreadcrumbItem>
          <BreadcrumbItem>{{drillDetail.name}}</BreadcrumbItem>
        </Breadcrumb>-->
    <!-- <div style="color: rgb(27, 76, 184);margin-bottom: 15px">
			<div class="addressIcon"></div>
			<span>当前位置：</span>
			<span style="cursor: pointer" @click="returnPage">{{ title }}</span>
			<Icon type="ios-arrow-forward" color="rgb(27, 76, 184)" size="16" />
			<span style="color: #333">{{drillDetail.name}}</span>
		</div> -->
    <div style="margin-bottom: 20px;" class="sceneStep">
      <template>
        <div class="step-group">
          <Steps :current="currentIndex" direction="vertical" style="width: 100%;">
            <Step
              title="赛前设置"
              @click.native="toPreCompeManage"
              content="提供竞赛前竞赛团队、题目、成员以及必要任务的管理."
              :class="{ curStep: drillStatus == 1 }"
              :icon="drillStatus == 1 ? 'ios-refresh-circle' : ''"
            ></Step>
            <Step
              :title="'赛中管理' + (drillDetail.progress == 5 ? '(已暂停)' : '')"
              @click.native="toCompeingManage"
              content="提供竞赛过程中的控制,比如开启关闭竞赛、修改题目信息、对题目显示隐藏的控制、团队禁赛恢复竞赛、切换竞赛环境、比赛过程中答题情况的监控等."
              :class="{ curStep: drillStatus == 2 }"
              :icon="drillStatus == 2 ? 'ios-refresh-circle' : ''"
            ></Step>
            <Step
              title="赛后归档"
              @click.native="toCompeedManage"
              content="提供赛后选手成绩的管理和统计."
              :class="{ curStep: drillStatus == 3 }"
              :icon="drillStatus == 3 ? 'ios-refresh-circle' : ''"
            ></Step>
          </Steps>
          <p
            style="color:#f00;"
            v-if="projectInfo.status == 3 && drillDetail.progress == 4 && endClearConfig"
          >
            【您的环境将于<Time
              :time="destoryTime"
              type="datetime"
            />时自动回收，若仍需保留，请在回收前重新开始配置比赛】
          </p>
        </div>
      </template>
      <div class="countdown" v-if="drillDetail.progress != 4">
        <template v-if="drillDetail.progress != 5">
          <span v-if="drillStatus == 1">开始</span
          ><span v-if="drillStatus != 1">结束</span>倒计时：<b>
            <span>{{ time.h }}</span
            >:<span>{{ time.m }}</span
            >:<span>{{ time.s }}</span></b
          >
        </template>
        <strong v-else>
          暂停中
        </strong>
      </div>
      <!--<div style="display:flex;justify-content: space-between;">-->
      <!--:style="{width:drillDetail.progress != 4 ? 'calc(50% - 130px)':''}"-->
      <div class="btn-group">
        <!--<span style="color:#f00;" v-if="projectInfo.status == 3 && drillDetail.progress == 4">【您的环境将于<Time :time="destoryTime" type="datetime" />时自动回收，若仍需保留，请在回收前重新开始配置比赛】</span>-->
        <div class="flex">
          <Poptip
            confirm
            title="确定要释放本次比赛的资源吗？如果确定本次比赛的结果已经统计完毕，请继续。"
            @on-ok="clearProject()"
            transfer
            word-wrap
            width="250"
          >
            <Button type="primary" :ghost="destoryProject()" :disabled="destoryProject()">
              <img src="../../assets/scene/dis-not-deploy.png" alt="" v-if="destoryProject()" />
              <img src="../../assets/scene/not-deploy.png" alt="" v-else />
              <span v-if="projectInfo.status == 14 || projectInfo.status == 3">释放资源</span>
              <span v-else>{{ projectInfo.statusCHName }}</span>
            </Button>
          </Poptip>
          <Poptip
            confirm
            title="为确保可视化展示效果，建议使用chrome浏览器查看大屏。"
            @on-ok="showVisualization()"
            transfer
            word-wrap
            width="250"
          >
            <Button type="primary">
              <img src="../../assets/scene/dis-screen.png" />可视化展示
            </Button>
          </Poptip>
          <Poptip
            confirm
            title="为确保可视化展示效果，建议使用chrome浏览器查看大屏。"
            @on-ok="showVisualizationAnswer()"
            transfer
            word-wrap
            width="250"
          >
            <Button type="primary">
              <img src="../../assets/scene/dis-screen.png" />可视化答题板
            </Button>
          </Poptip>
          <!--<Dropdown style="margin-left: 20px">
                      <Button type="primary">
                                         可视化展示
                        <Icon type="ios-arrow-down"></Icon>
                      </Button>
                      <DropdownMenu slot="list">
                      -->
          <!--<DropdownItem @click.native="showVisualization('common')">通用版</DropdownItem>-->
          <!--<DropdownItem @click.native="showVisualization('pcb')">鹏城版</DropdownItem>-->
          <!--</DropdownMenu>
                  </Dropdown> -->
          <!--
                    <Button type="primary" @click="changeCompetitionStatus('before')" :disabled="beforeContestStatus">
                      <Icon type="md-checkmark" />测试阶段</Button>
                    -->
          <!--<Button type="primary" @click="getTaskList('2')" :disabled="startContestStatus" v-if="drillDetail.progress != 4">
                      <img src="../../assets/scene/dis-start-scene.png" alt="" v-if="startContestStatus"/>
                      <img src="../../assets/scene/start-scene.png" alt="" v-else/>开始比赛</Button>
                    <Button type="primary" @click="showModal" v-if="drillDetail.progress == 4">
                      <img src="../../assets/scene/start-scene.png" alt=""/>重新开始比赛</Button>
                    <Button type="primary" :ghost="stopContestStatus" @click="getTaskList('4')" :disabled="stopContestStatus">
                      <img src="../../assets/scene/dis-stop-scene.png" alt="" v-if="stopContestStatus"/>
                      <img src="../../assets/scene/stop-scene.png" alt="" v-else/>结束比赛</Button>
                    <Button type="primary" :ghost="drillDetail.progress != 2" @click="changeCompetitionStatus(5)" :disabled="drillDetail.progress != 2" v-if="drillDetail.progress != 5">
                      <img src="../../assets/scene/dis-stop-scene.png" alt="" v-if="drillDetail.progress != 2"/>
                      <img src="../../assets/scene/stop-scene.png" alt="" v-else/>暂停比赛</Button>
                    <Button type="primary" :ghost="drillDetail.progress != 5" @click="changeCompetitionStatus(2)" :disabled="drillDetail.progress != 5" v-if="drillDetail.progress == 5">
                      <img src="../../assets/scene/dis-start-scene.png" alt="" v-if="drillDetail.progress != 5"/>
                      <img src="../../assets/scene/start-scene.png" alt="" v-else/>恢复比赛</Button>-->
          <Poptip
            confirm
            title="确定要开始比赛？"
            @on-ok="getTaskList('2')"
            transfer
            v-if="drillDetail.progress != 4"
            word-wrap
          >
            <Button
              type="primary"
              :ghost="startContestStatus || disabledAllBtn || disStartCompete"
              :disabled="startContestStatus || disabledAllBtn || disStartCompete"
            >
              <img
                src="../../assets/scene/dis-start-scene.png"
                alt=""
                v-if="startContestStatus || disabledAllBtn || disStartCompete"
              />
              <img src="../../assets/scene/start-scene.png" alt="" v-else />开始比赛</Button
            >
          </Poptip>
          <Button
            type="primary"
            @click="showModal('重新开始比赛', ['Dates'], saveScene, 120)"
            v-if="drillDetail.progress == 4"
            :ghost="disabledAllBtn"
            :disabled="disabledAllBtn"
          >
            <img src="../../assets/scene/dis-start-scene.png" alt="" v-if="disabledAllBtn" />
            <img src="../../assets/scene/start-scene.png" alt="" v-else />重新开始比赛</Button
          >
          <Button
            type="primary"
            @click="showDelayModal()"
            v-if="drillStatus == 2"
            :ghost="disabledAllBtn"
            :disabled="disabledAllBtn"
          >
            <img src="../../assets/scene/dis-delay.png" alt="" v-if="disabledAllBtn" />
            <img src="../../assets/scene/delay.png" alt="" v-else />延迟比赛</Button
          >
          <Button
            type="primary"
            @click="showExtraCreditModal()"
            v-if="drillStatus == 1 && isExtraCredit"
            :ghost="disabledAllBtn"
            :disabled="disabledAllBtn"
          >
            <img src="../../assets/scene/dis-start-scene.png" alt="" v-if="disabledAllBtn" />
            <img src="../../assets/scene/start-scene.png" alt="" v-else />修改激励分配置</Button
          >
          <Poptip
            confirm
            title="确定要重置环境？"
            @on-ok="resetEnviron()"
            transfer
            v-if="drillDetail.progress == 4 && cloudType !== 'h3c'"
            word-wrap
          >
            <Button
              type="primary"
              :ghost="disabledAllBtn || resetStatus == 1"
              :disabled="disabledAllBtn || resetStatus == 1"
            >
              <template v-if="resetStatus == 1">
                <Progress
                  :percent="resetProgress"
                  :stroke-width="10"
                  style="width:90px"
                  v-if="resetStatus == 1 && drillDetail.progress == 4"
                >
                  <span>重置{{ resetProgress }}%</span>
                </Progress>
                <!--<Icon type="ios-information-circle-outline" :size="20" v-if="resetStatus == 2"/>-->
                <!--<p>正在重置环境...</p>-->
              </template>
              <template v-else>
                <img
                  src="../../assets/scene/dis-reset-network.png"
                  alt=""
                  height="16"
                  v-if="disabledAllBtn"
                />
                <img src="../../assets/scene/reset-network.png" alt="" height="16" v-else />重置环境
              </template>
              <!--{{resetStatus}}-->
              <Icon
                type="ios-information-circle-outline"
                :size="16"
                @click.stop="getResetDetail"
                v-if="resetFail"
                style="vertical-align:text-bottom;"
              />
            </Button>
          </Poptip>
          <Poptip confirm title="确定要结束比赛？" @on-ok="getTaskList('4')" transfer word-wrap>
            <Button
              type="primary"
              :ghost="stopContestStatus || disabledAllBtn"
              :disabled="stopContestStatus || disabledAllBtn"
            >
              <img
                src="../../assets/scene/dis-stop-scene.png"
                alt=""
                v-if="stopContestStatus || disabledAllBtn"
              />
              <img src="../../assets/scene/stop-scene.png" alt="" v-else />结束比赛</Button
            >
          </Poptip>
          <Poptip
            confirm
            title="确定要暂停比赛？"
            @on-ok="pauseCompetition"
            transfer
            v-if="drillDetail.progress != 5"
            word-wrap
          >
            <Button
              type="primary"
              :ghost="drillDetail.progress != 2 || disabledAllBtn"
              :disabled="drillDetail.progress != 2 || disabledAllBtn"
            >
              <img
                src="../../assets/scene/dis-pause-scene.png"
                alt=""
                v-if="drillDetail.progress != 2 || disabledAllBtn"
              />
              <img src="../../assets/scene/pause-scene.png" alt="" v-else />暂停比赛</Button
            >
          </Poptip>
          <Poptip
            confirm
            title="确定要恢复比赛？"
            @on-ok="restoreCompetition"
            transfer
            v-if="drillDetail.progress == 5"
            word-wrap
          >
            <Button
              type="primary"
              :ghost="drillDetail.progress != 5 || disabledAllBtn"
              :disabled="drillDetail.progress != 5 || disabledAllBtn"
            >
              <img
                src="../../assets/scene/dis-recover-scene.png"
                alt=""
                v-if="drillDetail.progress != 5 || disabledAllBtn"
              />
              <img src="../../assets/scene/recover-scene.png" alt="" v-else />恢复比赛</Button
            >
          </Poptip>
          <Button type="primary" @click="boardModal = true">
            <img src="../../assets/scene/dis-boardcast.png" alt="" />发送公告</Button
          >
          <Button type="primary" @click="gotoReportPage" v-if="drillDetail.progress == 4">
            <img src="../../assets/scene/btn-report.png" />报告</Button
          >
          <Poptip
            confirm
            title="确定要清空场景公告及聊天消息？"
            @on-ok="clearSceneNoticeAndChat()"
            transfer
            word-wrap
          >
            <Button type="primary" :ghost="disabledAllBtn" :disabled="disabledAllBtn"
              >清空场景公告及聊天信息</Button
            >
          </Poptip>
          <Button
            type="primary"
            @click="handleGoCircumstances"
            v-if="$store.state.common.sysConfig.modeConfig != '1'"
            >进入环境</Button
          >
          <!--<Button type="warning" v-if="drillDetail.progress != 4"><span v-if="drillStatus == 1">开始</span><span v-if="drillStatus != 1">结束</span>倒计时：<span><span>{{time.h}}</span>:<span>{{time.m}}</span>:<span>{{time.s}}</span></span></Button>-->
          <!--compReportModal = true-->
        </div>
        <div style="margin-top:5px;">
          <span style="color:#ff9900;font-size:14px"
            ><Icon
              type="ios-information-circle-outline"
              :size="16"
            />开始比赛前请先完成团队人员配置和题目分配,如果已经完成配置,开始按钮不可点, 请点击</span
          ><a @click="validateStart" :disabled="disabledAllBtn" style="font-size: 14px;">校验</a>
        </div>
        <div style="margin-top:5px;">
          <span style="color:#ff9900;font-size:14px"
            ><Icon
              type="ios-information-circle-outline"
              :size="16"
            />如果比赛环境已经被改变，“重新开始比赛”前请先“重置环境”</span
          >
        </div>
        <ChatRoom
          v-if="!notOwn"
          :drillId="drillId"
          :isDistributed="isDistributed"
          class="btn-chat"
          ref="chatRoom"
        ></ChatRoom>
      </div>
    </div>
    <div class="span-group">
      <span style="margin-right: 10px;">
        配置模式：<Tag color="blue">{{ configMode === 1 ? '简单模式' : '复杂模式' }}</Tag>
        <Poptip
          confirm
          :title="configModeTitle"
          :disabled="disabledAllBtn"
          @on-ok="changeConfigMode"
        >
          <Button
            type="primary"
            shape="circle"
            icon="md-repeat"
            style="padding: 0;"
            :disabled="disabledAllBtn"
            size="small"
          ></Button>
        </Poptip>
      </span>
      <template v-if="isPartialBuilding">
        <span style="margin-right: 10px;">
          参赛选手可同时开机数量：<Tag color="blue">{{
            vmFormValidate.showNum || runningVmNum
          }}</Tag>
          <Button
            type="primary"
            shape="circle"
            icon="md-create"
            style="padding: 0;"
            size="small"
            :disabled="disabledAllBtn"
            @click="
              vmFormValidate.runningVmModal = true
              vmFormValidate.runningVmNum = vmFormValidate.showNum || runningVmNum
            "
          ></Button>
        </span>
      </template>

      <span style="margin-right: 10px;">
        是否可提交报告：<Tag color="blue">{{ isReportSubmit == 0 ? '否' : '是' }}</Tag>
        <Poptip confirm :title="reportSubmitTitle" @on-ok="changeReportSubmit">
          <Button
            type="primary"
            shape="circle"
            icon="md-repeat"
            style="padding: 0;"
            :disabled="disabledAllBtn"
            size="small"
          ></Button>
        </Poptip>
      </span>
      <span style="margin-right: 10px;">
        是否盲打：<Tag color="blue">{{ isBlindPlay == 0 ? '否' : '是' }}</Tag>
        <Poptip confirm :title="blindPlayTitle" @on-ok="changeBlindPlay">
          <Button
            type="primary"
            :disabled="touchType === 2 || disabledAllBtn"
            shape="circle"
            icon="md-repeat"
            style="padding: 0;"
            size="small"
          ></Button>
        </Poptip>
      </span>

      <template v-if="isBasicScore">
        <span style="margin-right: 10px;">
          得分扣分比例：<Tag color="blue">{{ basicDeduction }}%</Tag>
        </span>
      </template>
      <template v-else>
        <span style="margin-right: 10px;">
          是否允许申请提示：<Tag color="blue">{{
            isAllowApplicationPrompt == 0 ? '否' : '是'
          }}</Tag>
          <Poptip confirm :title="applicationPromptPlayTitle" @on-ok="changeAllowApplicationPrompt">
            <Button
              type="primary"
              :disabled="drillStatus == 3 || disabledAllBtn"
              shape="circle"
              icon="md-repeat"
              style="padding: 0;"
              size="small"
            ></Button>
          </Poptip>
        </span>
        <template v-if="isAllowApplicationPrompt != 0">
          <span style="margin-right: 10px;">
            申请提示扣分比例：<Tag color="blue">{{ ctfDeduction }}%</Tag>
            <Button
              type="primary"
              :disabled="drillStatus == 3 || disabledAllBtn"
              shape="circle"
              icon="md-repeat"
              @click="
                ctfDeductionFormValidate.show = true
                ctfDeductionFormValidate.ctfDeduction = ctfDeduction
              "
              style="padding: 0;"
              size="small"
            ></Button>
          </span>
        </template>
        <span style="margin-right: 10px">
          报告提交频率：<Tag color="blue"
            >（{{ submitTime }}分钟）内仅可提交 （{{ submitCount }}次）</Tag
          >
          <Button
            type="primary"
            shape="circle"
            icon="md-repeat"
            @click="
              showModal('修改报告提交频率', ['submitTime', 'submitCount'], modifyExtension, 180)
            "
            style="padding: 0"
            size="small"
          ></Button>
        </span>
      </template>
      <span style="margin-right: 10px">
        比赛结束后24小时是否自动销毁环境：<Tag color="blue">{{ endClearConfigShow }}</Tag>
        <Poptip
          confirm
          :title="changeEndClearConfigTip"
          :disabled="disChangeEndClearConfig"
          @on-ok="changEndClearConfig()"
        >
          <Button
            type="primary"
            shape="circle"
            icon="md-repeat"
            style="padding: 0"
            :disabled="disChangeEndClearConfig"
            size="small"
          ></Button>
        </Poptip>
      </span>
      <!--      上面是有操作按钮的-->
      <!--      下面是无操作按钮的-->
      <span style="margin-right: 10px;" v-if="!(onlineMode === 1 && vpn)">
        备用环境套数：<Tag color="blue">{{ environInfo.spareEnvNum }}</Tag>
      </span>
      <span style="margin-right: 10px;" v-show="envType === 1">
        允许虚拟接入：<Tag color="blue">{{ environInfo.vmInEnable ? '是' : '否' }} </Tag>
      </span>
      <span style="margin-right: 10px;">
        允许实物接入：<Tag color="blue">{{ environInfo.pmInEnable ? '是' : '否' }}</Tag>
      </span>
      <span style="margin-right: 10px;">
        竞赛模式：<Tag color="blue">{{ onlineMode === 1 ? '线上' : '线下' }}</Tag>
      </span>
      <template v-if="onlineMode == 1">
        <span style="margin-right: 10px;" v-if="ipMode !== 'oneTeamOneIp'">
          外网IP：<Tag color="blue">{{ environInfo.outsideIP || '无' }}</Tag>
        </span>
        <span style="margin-right: 10px;">
          线上模式：<Tag color="blue">{{ onlineTypeShow }}</Tag>
        </span>
        <span style="margin-right: 10px;" v-if="vpn">
          IP模式：<Tag color="blue">{{
            ipMode === 'allTeamOneIp' ? '所以有团队一个IP' : '一个团队一个IP'
          }}</Tag>
        </span>
      </template>
      <template v-else>
        <span style="margin-right: 10px;">
          部署模式：<Tag color="blue">{{ deployMode === 2 ? '路由模式' : '数据通道模式' }}</Tag>
        </span>
      </template>

      <span style="margin-right: 10px;">
        提交报告模式：<Tag color="blue">{{ wpUpMode == 2 ? '针对题目提交' : '针对竞赛提交' }}</Tag>
      </span>
      <span v-if="showCtfEnvType && onlineMode === 0">
        环境类型：<Tag color="blue">{{ envType == 1 ? '独享环境' : '共享环境' }}</Tag>
      </span>
      <template v-if="isBlindPlay !== 0">
        <span style="margin-right: 10px;">
          盲打模式：<Tag color="blue">{{
            touchType == 1 ? '无法查看排行榜' : '无法得知答题正确性'
          }}</Tag>
        </span>
      </template>

      <br />
      <template v-if="isExtraCredit">
        <span style="margin-right: 10px;"
          >Top1:<Tag color="blue" class="tag-button"
            >团队数 {{ formValidate.ExtraCredit1 }} - 奖励分数
            {{ formValidate.ExtraCreditValue1 }}%</Tag
          ></span
        >
        <span style="margin-right: 10px;"
          >Top2:<Tag color="blue" class="tag-button"
            >团队数 {{ formValidate.ExtraCredit2 }} - 奖励分数
            {{ formValidate.ExtraCreditValue2 }}%</Tag
          ></span
        >
        <span style="margin-right: 10px;"
          >Top3:<Tag color="blue" class="tag-button"
            >团队数 {{ formValidate.ExtraCredit3 }} - 奖励分数
            {{ formValidate.ExtraCreditValue3 }}%</Tag
          ></span
        >
      </template>
    </div>
    <Tabs
      class="demo-tabs-style2 tabs-hidden-icon"
      @on-click="changePreTab"
      v-if="preCompeManagePanelShow"
      :value="preDefault"
    >
      <TabPane label="竞赛团队管理" name="accessGroup" key="pre-access-user-to-group" :index="1">
        <AccessUserToGroup
          :configMode="configMode"
          v-if="preDefault == 'accessGroup'"
          :onlineMode="onlineMode"
          :type="2"
          step="pre"
          :vmInEnable="environInfo.vmInEnable"
          :isSupergroup="isSupergroup"
          :disabledAllBtn="disabledAllBtn"
          :vpn="vpn"
          @setHasUser="setHasUser"
        ></AccessUserToGroup>
      </TabPane>
      <TabPane
        label="接入机器分配"
        name="accessVm"
        v-if="hasAccessMachine || (isDistributed == 1 && isMainRange == 0 && drillDetail.id)"
        key="pre-access-vm-to-user"
        :index="2"
      >
        <AccessVmToUser
          :configMode="configMode"
          v-if="preDefault == 'accessVm'"
          :type="2"
          step="pre"
          :disabledAllBtn="disabledAllBtn"
        ></AccessVmToUser>
      </TabPane>
      <TabPane label="竞赛题目管理" name="targetTeam" key="pre-target-team" :index="3">
        <TargetTeam
          :configMode="configMode"
          :progress="drillDetail.progress"
          v-if="preDefault == 'targetTeam'"
          :onlineMode="onlineMode"
          :envType="envType"
          :vpn="vpn"
          step="pre"
          :disabledAllBtn="disabledAllBtn"
          :drillDetailProgress="drillDetail.progress"
          @getTargetTeamList="getCtfTargetTeamList"
        ></TargetTeam>
      </TabPane>
      <TabPane label="题目分配" name="targetAllot" key="pre-target-allot" :index="4">
        <TargetAllot
          :deployMode="deployMode"
          :configMode="configMode"
          :isBasicScore="isBasicScore"
          v-if="preDefault == 'targetAllot'"
          :poll="false"
          step="pre"
          :onlineMode="onlineMode"
          :extension="extension"
          :disabledAllBtn="disabledAllBtn"
          :ip="environInfo.outsideIP"
          :gateway="environInfo.outsideGatewayIP"
          @setHasTarget="setHasTarget"
          :ctfDeduction="ctfDeduction"
        ></TargetAllot>
      </TabPane>
      <!-- 针对题目提交 -->
      <TabPane
        label="裁判分配"
        name="refereeAllot"
        key="pre-referee-allot"
        :index="5"
        v-if="wpUpMode == 2 && hasReportTarget"
      >
        <RefereeAllot
          v-if="preDefault == 'refereeAllot'"
          :disabledAllBtn="disabledAllBtn"
          :drillStatus="drillStatus"
        >
        </RefereeAllot>
      </TabPane>
      <TabPane label="路由规则下发记录" name="routerRules" :index="6">
        <RouterRules
          v-if="preDefault == 'routerRules'"
          :type="2"
          :onlineMode="onlineMode"
          :disabledAllBtn="disabledAllBtn"
          :deployMode="deployMode"
          :vpn="vpn"
          :ctfOnlineType="ctfOnlineType"
        ></RouterRules>
      </TabPane>
      <TabPane
        label="基础分配置"
        name="basicScoreConfig"
        v-if="isBasicScore"
        key="pre-basic-score-config"
        :index="7"
      >
        <BasicScoreConfig
          v-if="preDefault == 'basicScoreConfig'"
          :drillStatus="drillStatus"
          :disabledAllBtn="disabledAllBtn"
        ></BasicScoreConfig>
      </TabPane>
      <TabPane label="静态Flag配置" name="flagOut" key="pre-flag-out" :index="8">
        <FlagOut
          v-if="preDefault == 'flagOut'"
          :configMode="configMode"
          :type="2"
          :disabledAllBtn="disabledAllBtn"
          :isPartialBuilding="isPartialBuilding"
        ></FlagOut>
      </TabPane>
      <TabPane
        label="答题系统通道配置任务"
        name="protocol"
        v-if="(hsaProblemsystem || questionSystemShowTab) && !ctfVpn"
        key="pre-protocol"
        :index="9"
      >
        <Protocol
          :configMode="configMode"
          :onlineMode="onlineMode"
          v-if="preDefault == 'protocol'"
          :disabledAllBtn="disabledAllBtn"
          :isDistributed="isDistributed"
        ></Protocol>
      </TabPane>
      <!-- <TabPane label="答题环境路由配置" name="distributeRouter" key="pre-distribute-router" :index="9">
				<DistributeRouter :onlineMode="onlineMode" :type="2" v-if="preDefault == 'distributeRouter'"
								  :disabledAllBtn="disabledAllBtn"></DistributeRouter>
			</TabPane> -->
      <TabPane
        label="选手自带答题设备接入申请"
        name="physicalResource"
        v-if="hasOwnDevice || (isDistributed == 1 && isMainRange == 0 && drillDetail.id)"
        key="pre-physical-resource"
        :index="10"
      >
        <physicalResource
          :configMode="configMode"
          v-if="preDefault == 'physicalResource'"
          :disabledAllBtn="disabledAllBtn"
          :isDistributed="isDistributed"
        ></physicalResource>
      </TabPane>
      <TabPane label="Checker任务" name="checker" key="pre-checker" :index="11">
        <Checker
          :configMode="configMode"
          v-if="preDefault == 'checker'"
          :type="2"
          :disabledAllBtn="disabledAllBtn"
        ></Checker>
      </TabPane>
      <TabPane
        label="环境管理"
        name="environManage"
        v-if="isPartialBuilding"
        key="pre-environ-manage"
        :index="12"
      >
        <EnvironManage
          v-if="preDefault == 'environManage'"
          :batch="isPartialBuilding"
          :disabledAllBtn="disabledAllBtn"
        ></EnvironManage>
      </TabPane>
      <TabPane
        label="绑定摄像头"
        name="bindCamera"
        v-if="showCameraTab && isDistributed != 1"
        key="pre-bind-camera"
        :index="13"
      >
        <bind-camera
          v-if="preDefault == 'bindCamera'"
          :disabledAllBtn="disabledAllBtn"
        ></bind-camera>
      </TabPane>
      <TabPane label="分靶场信息" name="rangeInformation" v-if="isMainRange == 1" :index="14">
        <RangeInformation
          v-if="preDefault == 'rangeInformation'"
          :type="7"
          :disabledAllBtn="disabledAllBtn"
        ></RangeInformation>
      </TabPane>
      <TabPane v-if="ctfVpn" label="团队VPN管理" name="teamVPN" key="pre-teamVPN" :index="15">
        <vpnManage
          :type="1"
          v-if="preDefault == 'teamVPN'"
          :testId="drillId"
          :disabledAllBtn="disabledAllBtn"
        ></vpnManage>
      </TabPane>
      <TabPane v-if="ctfVpn" label="用户VPN管理" name="userVPN" key="pre-userVPN" :index="16">
        <vpnManage
          :type="2"
          v-if="preDefault == 'userVPN'"
          :testId="drillId"
          :disabledAllBtn="disabledAllBtn"
        ></vpnManage>
      </TabPane>
      <TabPane
        v-if="ctfVpn && ipMode === 'oneTeamOneIp'"
        label="外网统计"
        name="teamStatistics"
        key="pre-teamStatistics"
        :index="17"
      >
        <teamStatistics
          v-if="preDefault == 'teamStatistics'"
          :type="2"
          :progress="drillDetail.progress"
          :disabledAllBtn="disabledAllBtn"
        ></teamStatistics>
      </TabPane>
      <!-- @add-data="getOperatingRecordList"
          @del-data="getOperatingRecordList" -->
      <!-- <TabPane
        label="外网操作统计"
        name="networkOperatingRecord"
        v-if="allowChangeIp"
        key="pre-networkOperatingRecord"
        :index="18"
      >
        <NetworkOperatingRecord
          v-if="preDefault == 'networkOperatingRecord'"
          :type="5"
          :disabledAllBtn="disabledAllBtn"
        ></NetworkOperatingRecord>
      </TabPane> -->
    </Tabs>
    <Tabs
      class="demo-tabs-style2"
      @on-click="changeMidTab"
      v-if="compeingManagePanelShow"
      :value="midDefault"
    >
      <TabPane label="竞赛团队管理" name="accessGroup" key="mid-access-user-to-group" :index="1">
        <AccessUserToGroup
          :configMode="configMode"
          v-if="midDefault == 'accessGroup'"
          :type="2"
          step="mid"
          :vmInEnable="environInfo.vmInEnable"
          :isSupergroup="isSupergroup"
          :disabledAllBtn="disabledAllBtn"
        ></AccessUserToGroup>
      </TabPane>
      <TabPane
        label="接入机器分配"
        name="accessVm"
        v-if="hasAccessMachine || (isDistributed == 1 && isMainRange == 0 && drillDetail.id)"
        key="mid-access-vm-to-user"
        :index="2"
      >
        <AccessVmToUser
          :configMode="configMode"
          v-if="midDefault == 'accessVm'"
          :type="2"
          step="mid"
        ></AccessVmToUser>
      </TabPane>
      <TabPane label="竞赛题目管理" name="targetTeamMid" key="mid-target-team" :index="3">
        <!--:show="midDefault == 'targetTeamMid'"-->
        <TargetTeam
          :progress="drillDetail.progress"
          v-if="midDefault == 'targetTeamMid'"
          :type="2"
          :poll="true"
          step="mid"
          :onlineMode="onlineMode"
          :envType="envType"
          :disabledAllBtn="disabledAllBtn"
          :drillDetailProgress="drillDetail.progress"
          @getTargetTeamList="getCtfTargetTeamList"
        ></TargetTeam>
      </TabPane>
      <TabPane
        label="裁判分配"
        name="refereeAllot"
        key="mid-referee-allot"
        :index="4"
        v-if="wpUpMode == 2 && hasReportTarget"
      >
        <RefereeAllot
          v-if="midDefault == 'refereeAllot'"
          :disabledAllBtn="disabledAllBtn"
          :drillStatus="drillStatus"
        >
        </RefereeAllot>
      </TabPane>
      <TabPane label="竞赛排名统计" name="teamRankStatic" key="mid-team-rank-static" :index="5">
        <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
        <teamRankStatic
          v-if="midDefault == 'teamRankStatic'"
          :poll="true"
          :hasReportTarget="hasReportTarget"
          :isBasicScore="isBasicScore"
          :disabledAllBtn="disabledAllBtn"
          :isDistributed="isDistributed"
          :isMainRange="isMainRange"
          :wpUpMode="wpUpMode"
        ></teamRankStatic>
      </TabPane>
      <TabPane
        label="大组排名统计"
        name="bigTeamRankStatic"
        v-if="isSupergroup"
        key="mid-big-team-rank-static"
        :index="6"
      >
        <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
        <bigTeamRankStatic
          v-if="midDefault == 'bigTeamRankStatic'"
          :poll="true"
        ></bigTeamRankStatic>
      </TabPane>
      <TabPane
        label="题目解答统计"
        name="questionSolveStatic"
        key="mid-question-solve-static"
        :index="7"
      >
        <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
        <questionSolveStatic v-if="midDefault == 'questionSolveStatic'"></questionSolveStatic>
      </TabPane>
      <TabPane label="竞赛答题监控" name="TargetAllot" key="mid-target-allot" :index="8">
        <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
        <TargetAllot
          :deployMode="deployMode"
          v-if="midDefault == 'TargetAllot'"
          :poll="true"
          :extension="extension"
          :isBasicScore="isBasicScore"
          :disabledAllBtn="disabledAllBtn"
          :drillStatus="drillStatus"
          step="mid"
          :ctfDeduction="ctfDeduction"
        ></TargetAllot>
      </TabPane>
      <TabPane label="提交统计" name="submitRecord" key="mid-submit-record" :index="9">
        <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
        <submitRecord
          :isBasicScore="isBasicScore"
          v-if="midDefault == 'submitRecord'"
          :touchType="touchType"
          :poll="true"
          :type="2"
        ></submitRecord>
      </TabPane>
      <TabPane label="环境管理" name="environManage" key="mid-environ-manage" :index="10">
        <!--<Alert>提供的功能：提供参赛团队的提交flag记录，提供正确提交的撤销和恢复撤销。</Alert>-->
        <EnvironManage
          v-if="midDefault == 'environManage'"
          :batch="isPartialBuilding"
          :disabledAllBtn="disabledAllBtn"
        ></EnvironManage>
      </TabPane>
      <TabPane
        label="题目异常日志"
        name="targetExceptionLog"
        key="mid-target-exception-log"
        :index="11"
      >
        <!--<Alert>提供的功能：提供参赛团队的提交flag记录，提供正确提交的撤销和恢复撤销。</Alert>-->
        <TargetExceptionLog
          v-if="midDefault == 'targetExceptionLog'"
          :type="2"
        ></TargetExceptionLog>
      </TabPane>
      <TabPane
        label="选手接入机器录屏"
        name="tab6"
        v-if="hasAccessMachine || (isDistributed == 1 && isMainRange == 0 && drillDetail.id)"
        key="mid-screen-controller"
        :index="12"
      >
        <screenController
          v-if="midDefault == 'tab6'"
          :type="2"
          :isDistributed="isDistributed"
          :isMainRange="isMainRange"
        ></screenController>
      </TabPane>
      <TabPane
        label="绑定摄像头"
        name="bindCamera"
        v-if="showCameraTab"
        key="mid-bind-camera"
        :index="13"
      >
        <bind-camera
          v-if="midDefault == 'bindCamera'"
          :disabledAllBtn="disabledAllBtn"
        ></bind-camera>
      </TabPane>
    </Tabs>
    <Tabs
      class="demo-tabs-style2"
      @on-click="changeEndTab"
      v-if="compeedManagePanelShow"
      :value="endDefault"
    >
      <TabPane label="竞赛排名统计" name="teamRankStatic" key="end-team-rank-static" :index="1">
        <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
        <teamRankStatic
          v-if="endDefault == 'teamRankStatic'"
          :hasReportTarget="hasReportTarget"
          :isBasicScore="isBasicScore"
          :disabledAllBtn="disabledAllBtn"
          :isDistributed="isDistributed"
          :isMainRange="isMainRange"
          :wpUpMode="wpUpMode"
        ></teamRankStatic>
      </TabPane>
      <TabPane
        label="大组排名统计"
        name="bigTeamRankStatic"
        v-if="isSupergroup"
        key="end-big-team-rank-static"
        :index="2"
      >
        <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
        <bigTeamRankStatic
          v-if="endDefault == 'bigTeamRankStatic'"
          :poll="true"
        ></bigTeamRankStatic>
      </TabPane>
      <!-- <TabPane label="团队答题统计" name="teamSolveStatic" key="end-team-solve-static"> -->
      <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
      <!-- <teamSolveStatic v-if ="endDefault == 'teamSolveStatic'"></teamSolveStatic>
			</TabPane> -->
      <TabPane
        label="题目解答统计"
        name="questionSolveStatic"
        key="end-question-solve-static"
        :index="3"
      >
        <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
        <questionSolveStatic v-if="endDefault == 'questionSolveStatic'"></questionSolveStatic>
      </TabPane>
      <TabPane label="竞赛答题监控" name="TargetAllot" key="end-target-allot" :index="4">
        <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
        <TargetAllot
          :isBasicScore="isBasicScore"
          :deployMode="deployMode"
          v-if="endDefault == 'TargetAllot'"
          :extension="extension"
          :drillStatus="drillStatus"
          :disabledAllBtn="disabledAllBtn"
          step="end"
          :ctfDeduction="ctfDeduction"
        ></TargetAllot>
      </TabPane>
      <TabPane label="提交统计" name="submitRecord" key="end-submit-record" :index="5">
        <!--<Alert>提供的功能：提供选手团队的得分排名</Alert>-->
        <submitRecord
          :isBasicScore="isBasicScore"
          v-if="endDefault == 'submitRecord'"
          :type="2"
          :showStatus="true"
        ></submitRecord>
      </TabPane>
      <TabPane label="报告统计" name="reportStatic" key="end-report-list" :index="6">
        <ReportList
          v-if="endDefault == 'reportStatic'"
          :wpUpMode="wpUpMode"
          :typ="2"
          :disabledAllBtn="disabledAllBtn"
        ></ReportList>
      </TabPane>
      <TabPane
        label="团队积分"
        name="adwTeamIntegral"
        v-if="!isBasicScore"
        key="end-adw-drill-integral-team"
        :index="7"
      >
        <!--<Alert>提供的功能：提供参赛团队的有效积分排名，同时提供团队积分的计算和积分排名的导出。</Alert>-->
        <adwDrillIntegral
          v-if="endDefault == 'adwTeamIntegral'"
          :type="0"
          :sceneType="2"
          :disabledAllBtn="disabledAllBtn"
        ></adwDrillIntegral>
      </TabPane>
      <TabPane
        label="个人积分"
        name="adwUserIntegral"
        v-if="!isBasicScore"
        key="end-adw-drill-integral-user"
        :index="8"
      >
        <!--<Alert>提供的功能：提供参赛个人的有效积分排名，同时提供个人积分的计算和积分排名的导出。</Alert>-->
        <adwDrillIntegral
          v-if="endDefault == 'adwUserIntegral'"
          :type="1"
          :sceneType="2"
          :disabledAllBtn="disabledAllBtn"
        ></adwDrillIntegral>
      </TabPane>
      <TabPane label="录屏回放" name="tab6" v-if="hasAccessMachine" :index="9">
        <screenController
          v-if="endDefault == 'tab6'"
          :poll="false"
          :type="2"
          :isDistributed="isDistributed"
          :isMainRange="isMainRange"
        ></screenController>
      </TabPane>
    </Tabs>
    <Modal v-model="vmFormValidate.runningVmModal" title="修改参赛选手可同时开机数量" :width="650">
      <Form ref="vmFormValidate" :model="vmFormValidate" :rules="vmRuleValidate" :label-width="130">
        <FormItem label="参赛选手可同时开机数量" prop="runningVmNum">
          <InputNumber
            style="width: 100%;"
            :max="needEnvVmNum"
            :min="1"
            :placeholder="`设置范围：1~${needEnvVmNum}`"
            v-model="vmFormValidate.runningVmNum"
          ></InputNumber>
        </FormItem>
      </Form>
      <div slot="footer">
        <Button
          @click="
            vmFormValidate.runningVmModal = false
            handleReset('vmFormValidate')
          "
          >取消</Button
        >
        <Button @click="changeRunVmNum" type="primary">确定</Button>
      </div>
    </Modal>
    <Modal v-model="ctfDeductionFormValidate.show" title="修改扣分比例">
      <Form
        ref="ctfDeductionFormValidate"
        :model="ctfDeductionFormValidate"
        :label-width="120"
        :rules="ctfDeductionRuleValidate"
      >
        <FormItem label="申请提示扣分比例" prop="ctfDeduction">
          <InputNumber
            style="width: 100%;"
            :max="100"
            :min="1"
            :placeholder="`设置范围：1~100`"
            v-model="ctfDeductionFormValidate.ctfDeduction"
          ></InputNumber>
        </FormItem>
      </Form>
      <div slot="footer">
        <Button
          @click="
            ctfDeductionFormValidate.show = false
            handleReset('ctfDeductionFormValidate')
          "
          >取消</Button
        >
        <Button @click="changeCtfDeduction" type="primary">确定</Button>
      </div>
    </Modal>
    <Modal v-model="boardModal" title="发送公告" :width="650" footer-hide>
      <board
        v-if="boardModal"
        @hideModal="hideModal"
        :isDistributed="isDistributed"
        :isMainRange="isMainRange"
      ></board>
    </Modal>
    <Modal
      v-model="sceneModal.show"
      :title="sceneModal.title"
      :loading="sceneModal.loading"
      :mask-closable="false"
      @on-ok="handleSceneModalOk"
      @on-cancel="handleReset('timeFormValidate')"
      :width="600"
    >
      <Form
        ref="timeFormValidate"
        :model="formValidate"
        :rules="ruleValidate"
        :label-width="sceneModal.labelWidth"
      >
        <FormItem label="时间" prop="Dates" v-if="sceneModal.prop.includes('Dates')">
          <DatePicker
            :editable="false"
            type="datetimerange"
            :value="formValidate.Dates"
            format="yyyy-MM-dd HH:mm"
            placement="bottom-start"
            confirm
            ref="datePicker"
            placeholder="选择日期"
            style="width: 280px"
            transfer
            @on-ok="clickOkBtn"
            @on-clear="clickClearBtn"
            @on-open-change="switchOpenChange"
            @on-change="changeDates"
          ></DatePicker>
          <p style="color:#ff9900;font-size:10px">选择同一天的时间段请双击要选择的日期</p>
        </FormItem>
        <div
          class="flex"
          style="line-height: 32px"
          v-if="sceneModal.prop.includes('submitTime') && sceneModal.prop.includes('submitCount')"
        >
          报告提交频率设置
          <FormItem
            label=" "
            prop="submitTime"
            :label-width="34"
            key="submitTime"
            v-if="sceneModal.prop.includes('submitTime')"
            style="margin-bottom:0"
          >
            <div style="display: flex; align-items: center">
              <InputNumber
                v-model="formValidate.submitTime"
                :min="1"
                :max="100"
                :placeholder="'输入1~100的整数'"
                style="width: 140px; border-radius: 4px 0 0 4px"
              >
              </InputNumber>
              <div class="input-append"><span>分钟</span></div>
            </div>
          </FormItem>
          <FormItem
            label=" "
            prop="submitCount"
            :label-width="34"
            key="submitCount"
            v-if="sceneModal.prop.includes('submitCount')"
            style="margin-bottom:0"
          >
            <div style="display: flex; align-items: center">
              <InputNumber
                v-model="formValidate.submitCount"
                :min="1"
                :max="100"
                :placeholder="'输入1~100的整数'"
                style="width: 140px; border-radius: 4px 0 0 4px"
              >
              </InputNumber>
              <div class="input-append"><span>次</span></div>
            </div>
          </FormItem>
        </div>
      </Form>
    </Modal>
    <Modal
      v-model="sceneDelayModal.show"
      :title="sceneDelayModal.title"
      :loading="sceneDelayModal.loading"
      :mask-closable="false"
      @on-ok="saveSceneDelayTime('formValidate1')"
      @on-cancel="handleReset('formValidate1')"
      :width="600"
    >
      <Form ref="formValidate1" :model="formValidate" :rules="delayRuleValidate" :label-width="80">
        <FormItem label="结束时间" prop="endDate">
          <DatePicker
            :editable="false"
            type="datetime"
            v-model="formValidate.endDate"
            :value="formValidate.endDate"
            format="yyyy-MM-dd HH:mm"
            placement="bottom-start"
            placeholder="选择日期"
            style="width: 280px"
            transfer
            @on-change="changeEndDate"
          ></DatePicker>
        </FormItem>
      </Form>
    </Modal>
    <Modal
      v-model="sceneExtraCreditModal.show"
      :title="sceneExtraCreditModal.title"
      :loading="sceneExtraCreditModal.loading"
      :mask-closable="false"
      @on-ok="saveSceneExtraCredit('formValidate')"
      @on-cancel="handleReset('formValidate')"
      :width="600"
    >
      <Form ref="formValidate" :model="incentivesObj" :rules="ruleValidate" :label-width="80">
        <div>
          <p class="levelConfig">
            Top1
            <FormItem label=" " prop="ExtraCredit1" :label-width="12" style="margin-left:10px">
              <div class="levelConfig-label levelConfig-label-small">团队数</div>
              <InputNumber
                style="width: 130px;"
                :max="100"
                :min="1"
                placeholder="设置范围：1~100"
                v-model="incentivesObj.ExtraCredit1"
              ></InputNumber>
            </FormItem>
            <FormItem label=" " prop="ExtraCreditValue1" :label-width="12" style="margin-left:10px">
              <div class="levelConfig-label levelConfig-label-long">奖励分数(%)</div>
              <InputNumber
                style="width: 130px;"
                :max="100"
                :min="1"
                placeholder="设置范围：1~100"
                v-model="incentivesObj.ExtraCreditValue1"
              ></InputNumber>
            </FormItem>
          </p>
          <p class="levelConfig">
            Top2
            <FormItem label=" " prop="ExtraCredit2" :label-width="12" style="margin-left:10px">
              <div class="levelConfig-label levelConfig-label-small">团队数</div>
              <InputNumber
                style="width: 130px;"
                :max="100"
                :min="1"
                placeholder="设置范围：1~100"
                v-model="incentivesObj.ExtraCredit2"
              ></InputNumber>
            </FormItem>
            <FormItem label=" " prop="ExtraCreditValue2" :label-width="12" style="margin-left:10px">
              <div class="levelConfig-label levelConfig-label-long">奖励分数(%)</div>
              <InputNumber
                style="width: 130px;"
                :max="100"
                :min="1"
                placeholder="设置范围：1~100"
                v-model="incentivesObj.ExtraCreditValue2"
              ></InputNumber>
            </FormItem>
          </p>
          <p class="levelConfig">
            Top3
            <FormItem label=" " prop="ExtraCredit3" :label-width="12" style="margin-left:10px">
              <div class="levelConfig-label levelConfig-label-small">团队数</div>
              <InputNumber
                style="width: 130px;"
                :max="100"
                :min="1"
                placeholder="设置范围：1~100"
                v-model="incentivesObj.ExtraCredit3"
              ></InputNumber>
            </FormItem>
            <FormItem label=" " prop="ExtraCreditValue3" :label-width="12" style="margin-left:10px">
              <div class="levelConfig-label levelConfig-label-long">奖励分数(%)</div>
              <InputNumber
                style="width: 130px;"
                :max="100"
                :min="1"
                placeholder="设置范围：1~100"
                v-model="incentivesObj.ExtraCreditValue3"
              ></InputNumber>
            </FormItem>
          </p>
        </div>
      </Form>
    </Modal>
    <Modal v-model="tipModal.show" :title="tipModal.title" width="300" footer-hide>
      <h4>
        <Icon
          type="ios-loading"
          size="24"
          class="demo-spin-icon-load"
          style="margin-right:24px;"
        ></Icon
        >{{ tipModal.content }}
      </h4>
    </Modal>
    <Modal v-model="resetDetailModal.show" :title="resetDetailModal.title" width="800" footer-hide>
      <Button type="primary" ghost size="small" @click="rebuildAllFailVm" v-if="resetFail">
        <img
          src="../../assets/scene/dis-reset-network.png"
          alt=""
          style="vertical-align: middle;"
        />重置所有重置失败节点
      </Button>
      <Table border :columns="resetCol" :data="resetInfo.msgs" style="margin-top:10px;"></Table>
    </Modal>
    <automation-step
      @on-window-state-change="windowStateChange"
      @finish="automationStepFinish"
      @on-config-suspend="configSuspend"
      :disabled="disabledAllBtn"
      :type="2"
      :isOnline="onlineMode == 1"
      :isDistributed="isDistributed"
      :vpn="vpn"
      :ctfOnlineType="ctfOnlineType"
    ></automation-step>
  </div>
</template>

<script>
import RangeInformation from '@/view/drill_compete/page/rangeInformation'
import TargetTeam from '@/view/drill_compete/page/targetTeam/targetTeam-ctf' //靶机
import TargetAllot from '@/view/drill_compete/page/targetTeam/targetTeamAllot-ctf'
import AccessVmToUser from '@/view/drill_compete/page/accessVmToUser'
import BasicScoreConfig from '@/view/drill_compete/page/basicScoreConfig'
import FlagCommitOnce from '@/view/drill_compete/page/task_new/flagCommitOnce'
import Checker from '@/view/drill_compete/page/task_new/checker'
import FlagOutLoop from '@/view/drill_compete/page/task_new/flagOutLoop.vue'
import FlagVmOnce from '@/view/drill_compete/page/flagVmOnce'
import ReportCommitLoop from '@/view/drill_compete/page/reportCommitLoop'
import AccessUserToGroup from '@/view/drill_compete/page/accessUserToGroup'
import TargetExceptionLog from '@/view/drill_compete/page/targetExceptionLog'
import Protocol from '@/view/drill_compete/page/protocol.vue'
import QGAWrite from '@/view/drill_compete/page/qgaWrite/qgawrite.vue'
import teamRankStatic from '@/view/drill_compete/page/statistics/ctfTeamRankStatic'
import bigTeamRankStatic from '@/view/drill_compete/page/statistics/bigCtfTeamRankStatic'
import questionSolveStatic from '@/view/drill_compete/page/statistics/ctfQuestionSolveStatic'
import adwDrillIntegral from '@/view/drill_compete/page/statistics/awdDrillIntegral.vue'
import submitRecord from '@/view/drill_compete/page/statistics/submitRecord.vue'
import FlagOut from '@/view/drill_compete/page/task_new/flagOut.vue'
import board from '@/components/board-cast/drillBoardcast.vue'
import DistributeRouter from '@/view/drill_compete/page/distributeRouter.vue'
import physicalResource from '@/view/drill_compete/page/physicalResource'
import EnvironManage from '@/view/drill_compete/page/environManage.vue'
import AutomationStep from '@/components/automation-step/automation-step'
import RouterRules from '@/view/drill_compete/page/router-rules' // 路由规则最新的下发记录
import ChatRoom from '@/components/chatRoom/chatRoom'
import ReportList from '@/view/drill_compete/page/report-list'
import BindCamera from '@/view/drill_compete/page/bind-camera'
import RefereeAllot from '@/view/drill_compete/page/targetTeam/refereeAssignTarget'
import vpnManage from '@/view/drill_compete/page/componentHW/vpnManage'
import TeamStatistics from '@/view/drill_compete/page/teamStatistics'
// import NetworkOperatingRecord from '@/view/drill_compete/page/network-operating-record'
import encryption from '@/libs/encryption.js'
import {
  getSceneInfo,
  updateSceneProgress,
  setSceneCycle,
  modifyScene,
  quickCreateProgress,
  batchOpVm,
  batchOpVmLog,
  batchOpVmLogOnce,
  rebuildVm,
  queryCtfTarget,
  queryNetworkList,
  queryVmWithParty,
  ctfTargetAllot,
  getExecutionsResult,
  queryCtfTargetAllot,
  addPRApply,
  calculateScore,
  getDevicePortsById,
  dnsConfig,
  batchModifyCtfTarget
} from '@/api/drill_compete'
import {
  clearProject,
  ctfFlowConfig,
  newSaveFlowDataByPrj,
  setCtfFlowRedis
} from '@/api/competition'
import {
  getTaskList,
  batchActiveTask,
  getstatusbyprjid,
  saveoutbandTask,
  getServerList,
  loadConfiguration,
  hxRouterVms,
  hostDetail
} from '@/api/drill'
import { sendToSence, sendToSenceDis } from '@/api/boardcast_new.js'
import {
  getaccessgrouplist,
  getuserinstance,
  setuservmrelation,
  getprojsubnet
} from '@/api/access_new.js'
import { opVms, queryVmStatus } from '@/api/remote'
import { clearSceneNoticeAndChat } from '@/api/boardcast_new.js'
import timer from '@/mixin/timer'
import commonFun from './mixin.js'
import screenController from '@/view/drill_compete/page/screenController'
import recoverTime from '@/mixin/recoverTime'
import { getDictInfoByName } from '@/api/dict'
import { parseJson } from '@/libs/utils'
import disRouteFun from '@/view/drill_compete/page/targetTeam/mixin'
import { toJSONString } from 'xe-utils'
import destroyEnv from '@/mixin/destroyEnvironmentMixin'
import resetSceneMixin from '@/mixin/resetSceneMixin'
import { getNumReg } from '@/libs/reg'
import { mapState } from 'vuex'
export default {
  name: 'scenes',
  mixins: [recoverTime],
  components: {
    RouterRules,
    screenController,
    TargetTeam, //靶机--演练前
    TargetAllot,
    //Flow, //流量过滤
    //TargetTeamMid, //靶机--演练中（type="mid"）会轮询，需传show,
    FlagCommitOnce, //flag单次提交
    Checker, //check任务
    FlagOutLoop, //
    FlagVmOnce, //Flag服务器配置
    AccessVmToUser, //（环境）接入机器
    BasicScoreConfig, // 基础分配置
    AccessUserToGroup, //（演练用户管理）分配用户
    TargetExceptionLog, //靶标异常日志,
    Protocol,
    QGAWrite,
    teamRankStatic,
    bigTeamRankStatic,
    questionSolveStatic,
    adwDrillIntegral, //排名统计,
    submitRecord, //提交统计
    FlagOut,
    board,
    //	        report,
    DistributeRouter,
    ReportCommitLoop,
    physicalResource,
    EnvironManage,
    ChatRoom,
    ReportList,
    BindCamera,
    AutomationStep,
    RangeInformation,
    RefereeAllot,
    vpnManage,
    TeamStatistics
    // NetworkOperatingRecord
  },
  mixins: [timer, commonFun, recoverTime, disRouteFun, destroyEnv, resetSceneMixin],
  data() {
    let September = sessionStorage.getItem('November')
    September = JSON.parse(encryption.SelfUseDecrypt(September))
    const validateDate = (rule, value, callback) => {
      //验证只能填入数字
      //var reg = new RegExp("^([1-9]|[1-9]\\d|100)$");
      //验证警戒值
      if (value) {
        let startTime = this.formValidate.Dates[0] || ''
        let endTime = this.formValidate.Dates[1] || ''
        if (!startTime || !endTime) {
          callback(new Error('请选择时间'))
        } else if (new Date(endTime).getTime() - new Date(startTime).getTime() < 60 * 60 * 1000) {
          callback(new Error('起止时间最小间隔一个小时'))
        } else {
          callback()
        }
      } else {
        callback()
      }
    }
    const validateNum1 = (rule, value, callback) => {
      //验证只能填入数字
      var reg = new RegExp('^([1-9]|[1-9]\\d|100)$')
      let _this = this
      //验证警戒值
      if (value || value === 0) {
        if (!reg.test(value)) {
          callback(new Error('请输入1-100的整数'))
        } else {
          callback()
        }
      } else {
        callback()
      }
    }
    const validateVmNum = (rule, value, callback) => {
      // 验证虚拟机可开机数量
      if (Number.isInteger(value)) {
        if (value < 1 || value > this.needEnvVmNum) {
          callback(new Error(`设置范围：1~${this.needEnvVmNum}`))
        } else {
          callback()
        }
      } else {
        callback(new Error('请输入整数'))
      }
    }
    const validateDelayDate = (rule, value, callback) => {
      //验证只能填入数字
      //var reg = new RegExp("^([1-9]|[1-9]\\d|100)$");
      //验证警戒值
      if (value) {
        if (new Date(value).getTime() - new Date(this.drillDetail.endTime).getTime() <= 0) {
          callback(new Error('选择的时间必许大于当前结束时间'))
        } else {
          callback()
        }
      } else {
        callback(new Error('请选择时间'))
      }
    }
    return {
      isDistributed: 0,
      isScheme: 0,
      isMainRange: 0,
      autoConfigIsFinish: false,
      isWindowed: false,
      configIsSuspend: false,
      ctfDeductionFormValidate: {
        ctfDeduction: 20,
        show: false
      },
      needEnvVmNum: 0, // 需要环境的虚拟机数量
      vmFormValidate: {
        runningVmModal: false,
        runningVmNum: 0,
        showNum: 0
      },
      accessGroupList: [], // 当前比赛用户组
      blindPlayTitle: '是否开启盲打模式', // 切换盲打状态时，提示框信息
      isBlindPlay: 0, // 是否盲打
      touchType: 1, // 盲打模式
      isAllowApplicationPrompt: 1, // 是否允许申请提示
      basicDeduction: 10,
      ctfDeduction: 20,
      isReportSubmit: 1, // 是否允许提交报告
      applicationPromptPlayTitle: '是否关闭提示申请',
      reportSubmitTitle: '是否关闭报告提交通道',
      configModeTitle: '是否切换至简单模式',
      USER_ID: September.userId,
      USER_Name: September.nickname,
      projectId: this.$route.query.prjid,
      drillId: this.$route.query.id,
      drillName: this.$route.query.name,
      drillDetail: {},
      currentIndex: 0,
      preCompeManagePanelShow: true,
      compeingManagePanelShow: false,
      compeedManagePanelShow: false,
      startContestStatus: false,
      stopContestStatus: false,
      preDefault: '',
      midDefault: '',
      endDefault: '',
      drillStatus: '',
      backObj: {
        path: '/ctfContest',
        name: 'ctfContest',
        query: {
          //pane:'drillSencen',
          page: this.$route.query.page
        },
        meta: {
          requireAuth: true
        }
      },
      project: {
        drillitemname: this.$route.query.name,
        projectid: this.$route.query.prjid,
        drillitemid: this.$route.query.id,
        testId: this.$route.query.id
      },
      projectInfo: {},
      timeoutP: {},
      timeout: {},
      boardModal: false,
      compReportModal: false,
      sceneModal: {
        show: false,
        title: '修改时间',
        loading: true,
        type: 1,
        width: 550,
        prop: []
      },
      sceneDelayModal: {
        show: false,
        title: '延迟比赛时间',
        loading: true,
        type: 1,
        width: 550
      },
      sceneExtraCreditModal: {
        show: false,
        title: '修改激励分配置',
        loading: true,
        type: 1,
        width: 550
      },
      formValidate: {
        //      	"createTime":"2020-02-13T08:55:46.545Z",
        //      	"creator":"string",
        cycleTime: 1,
        description: '',
        endTime: '',
        extension: '',
        iconPath: '',
        id: '',
        name: '',
        progress: 0, // 0.准备中、1.准备完毕、2.开始中、3.裁判评判阶段、4.结束
        projectId: '',
        projectName: '',
        startTime: '',
        status: 1, //0 ：不启用 1：启用
        type: 0, //0.对抗演练、1.攻防赛、2夺旗赛、3知识赛、4渗透演练
        Dates: [],
        stMode: 0,
        endDate: '',
        ExtraCreditValue1: 6,
        ExtraCreditValue2: 4,
        ExtraCreditValue3: 2,
        ExtraCredit1: 1,
        ExtraCredit2: 1,
        ExtraCredit3: 1,
        submitTime: 1,
        submitCount: 1
      },
      ctfDeductionRuleValidate: {
        ctfDeduction: [
          { required: true, type: 'number', message: '不能为空', trigger: 'change' },
          { validator: validateNum1, trigger: 'change' }
        ]
      },
      vmRuleValidate: {
        runningVmNum: [
          { required: true, type: 'number', message: '不能为空', trigger: 'change' },
          { validator: validateVmNum, trigger: 'change' }
        ]
      },
      ruleValidate: {
        Dates: [
          { required: true, type: 'array', message: '不能为空', trigger: 'change' },
          { validator: validateDate, trigger: 'change' }
        ],
        ExtraCreditValue1: [
          { required: true, type: 'number', message: '不能为空', trigger: 'change' },
          { validator: validateNum1, trigger: 'change' }
        ],
        ExtraCreditValue2: [
          { required: true, type: 'number', message: '不能为空', trigger: 'change' },
          { validator: validateNum1, trigger: 'change' }
        ],
        ExtraCreditValue3: [
          { required: true, type: 'number', message: '不能为空', trigger: 'change' },
          { validator: validateNum1, trigger: 'change' }
        ],
        ExtraCredit1: [
          { required: true, type: 'number', message: '不能为空', trigger: 'change' },
          { validator: validateNum1, trigger: 'change' }
        ],
        ExtraCredit2: [
          { required: true, type: 'number', message: '不能为空', trigger: 'change' },
          { validator: validateNum1, trigger: 'change' }
        ],
        ExtraCredit3: [
          { required: true, type: 'number', message: '不能为空', trigger: 'change' },
          { validator: validateNum1, trigger: 'change' }
        ],
        submitTime: [
          { required: true, type: 'number', message: '不能为空', trigger: 'change,blur' },
          { validator: getNumReg(100), trigger: 'change' }
        ],
        submitCount: [
          { required: true, type: 'number', message: '不能为空', trigger: 'change,blur' },
          { validator: getNumReg(100), trigger: 'change' }
        ]
      },
      delayRuleValidate: {
        endDate: [
          //	          	{ required: true,message: '不能为空', trigger: 'change' },
          { validator: validateDelayDate, trigger: 'change' }
        ]
      },
      onlineMode: 0,
      extension: {},
      isExtraCredit: false,
      disabledDestroy: false,
      environInfo: '',
      destoryTime: '',
      tipModal: {
        title: '提示',
        show: false,
        content: ''
      },
      queryOpLogInfo: {
        pageIndex: 1,
        pageSize: 1,
        projectId: this.$route.query.prjid,
        action: 'rebuild'
      },
      resetProgress: 0,
      resetInfo: {},
      resetStatus: 0,
      resetFail: false,
      resetDetailModal: {
        title: '重置详情',
        show: false
      },
      resetCol: [
        {
          title: '虚拟机名称',
          key: 'name'
        },
        {
          title: '实例名称',
          key: 'instanceName'
        },
        {
          title: '系统类型',
          key: 'sysType'
        },
        {
          title: '子网络名称',
          key: 'networkName'
        },
        {
          title: '镜像名称',
          key: 'imageName'
        },
        {
          title: '状态',
          key: 'errMsg',
          render: (h, params) => {
            return h(
              'Tag',
              {
                props: {
                  color: params.row.errMsg ? 'red' : 'green'
                }
              },
              params.row.errMsg ? '重置失败' : '重置成功'
            )
          }
        },
        {
          title: '错误信息',
          key: 'errMsg',
          render: (h, params) => {
            return h('span', params.row.errMsg || '无')
          }
        }
      ],
      showExtraCredit: false,
      showCameraTab: false,
      incentivesObj: {
        ExtraCredit1: 0,
        ExtraCreditValue1: 0,
        ExtraCredit2: 0,
        ExtraCreditValue2: 0,
        ExtraCredit3: 0,
        ExtraCreditValue3: 0
      },
      showCtfEnvType: false
    }
  },
  filters: {},
  provide() {
    return {
      parent: this
    }
  },
  beforeDestroy() {
    clearTimeout(this.timeout)
    clearInterval(this.timeoutP)
  },
  beforeRouteLeave(to, from, next) {
    if (to.path === '/ctfContest') {
      //to.query.page = this.$route.query.page
      next()
    } else {
      //跳转至非夺旗赛页面，清空存储的查询条件
      sessionStorage.removeItem('queryObj')
      next()
    }
  },
  watch: {
    refreshTime(val, oldVal) {
      if (val != oldVal) {
        this.getDrillDetail(true, true)
      }
    },
    isAllowApplicationPrompt: function(newValue) {
      if (newValue !== 0) {
        this.applicationPromptPlayTitle = '是否关闭提示申请'
      } else {
        this.applicationPromptPlayTitle = '是否开启提示申请'
      }
    },
    configMode: function(newValue) {
      if (newValue !== 2) {
        this.configModeTitle = '是否切换至复杂模式'
      } else {
        this.configModeTitle = '是否切换至简单模式'
      }
    },
    isReportSubmit: function(newValue) {
      if (newValue !== 0) {
        this.reportSubmitTitle = '是否关闭报告提交通道'
      } else {
        this.reportSubmitTitle = '是否打开报告提交通道'
      }
    },
    isBlindPlay: function(newValue) {
      if (newValue === 0) {
        this.blindPlayTitle = '是否开启盲打模式'
      } else {
        this.blindPlayTitle = '是否关闭盲打模式'
      }
    },
    drillStatus(val, oldVal) {
      if (val != oldVal && oldVal) {
        this.getDrillDetail(true, true)
      }
    }
  },
  async mounted() {
    this.currentProjectId = this.$route.query.prjid
    this.questionSystemShow('questionSystemConfig')
    //	this.getDrillSecensLists();
    await this.getProjectInfo()
    // 这个方法需要放在首位执行，后续方法需要依赖它获取数据
    await this.getDrillDetail(true, true).then((data) => {
      this.$store.commit('addBreadItem', { name: this.drillDetail.name })
      //判断是否可以开始比赛
      this.canStartCompete(this.drillDetail.type)
    })
    this.getCtfTargetTeamList()
    if (this.isDistributed == 0 || (this.isDistributed == 1 && this.isMainRange == 1)) {
      await quickCreateProgress(this.drillId).then((data) => {
        if (data.code === 1) {
          if (data.data) {
            this.environInfo = JSON.parse(data.data.paramJson)
            console.log(this.environInfo)
          }
        }
      })
    }
    this.hasCamera()
    //  	this.getCtfFlowConfigList();
    sessionStorage.removeItem('vmCurrentPage')
    this.getAccessGroupList()
    this.getVmNum()
    this.getDictInfoByName('ctfEnvType')
  },
  methods: {
    getDictInfoByName(name) {
      getDictInfoByName({ name })
        .then((res) => {
          if (res.code == 1) {
            this.showCtfEnvType = res.attribute.data.value === '1' ? true : false
          } else {
            this.showCtfEnvType = false
          }
        })
        .catch((err) => {
          this.showCtfEnvType = false
          console.log(err)
        })
    },

    //进入环境
    handleGoCircumstances() {
      if (this.$store.state.common.sysConfig.modeConfig == '2') {
        this.$Message.info('未授权功能，请联系管理员')
      } else if (this.$store.state.common.sysConfig.modeConfig == 'jizhi2024') {
        window.open(
          `/14-topologyProject/index.html#/topologyDisplay/topologys?projectId=${this.$route.query.prjid}`
        )
      }
    },
    // 监控子组件是否处于窗口状态，需要通过这个状态太判断是否需要禁用按钮功能
    windowStateChange(state) {
      this.isWindowed = state
    },
    // 自动配置完成，放开窗口状态监控，检测是否可以开始比赛
    automationStepFinish() {
      this.isWindowed = false
      this.canStartCompete(this.drillDetail.type)
    },
    // 未自动配置
    configSuspend(state) {
      this.configIsSuspend = state
    },
    awaitWrap(promise) {
      return promise.then((data) => [null, data]).catch((err) => [err, null])
    },
    hasCamera() {
      getDictInfoByName({
        name: 'cameraConfig'
      }).then((data) => {
        if (data.code == 1) {
          this.showCameraTab = data.attribute.data.value === '1'
        }
      })
    },
    // 查询需要环境的虚拟机数量
    getVmNum() {
      queryCtfTarget(this.$route.query.id, {
        pageIndex: 1,
        pageSize: 2147483647
      })
        .then((data) => {
          if (data.code == 1) {
            let vmList = data.data.items || data.data
            let num = 0 // 获取需要环境的虚拟机数量
            vmList.forEach((item) => {
              if (item.isNeedEnv === '1') {
                num++
              }
            })
            this.needEnvVmNum = num
          } else {
            this.$Message.error('获取列表失败')
          }
        })
        .catch((error) => {
          this.$Message.error('获取列表失败')
        })
    },
    // 切换是否盲打的状态
    changeBlindPlay() {
      let extension = JSON.parse(this.formValidate.extension)
      let isBlindPlay = extension.isBlindPlay || 0
      isBlindPlay = isBlindPlay === 0 ? 1 : 0 // 取反
      extension.isBlindPlay = isBlindPlay
      this.isBlindPlay = isBlindPlay
      this.formValidate.extension = JSON.stringify(extension)
      let formValidate = {
        extension: this.formValidate.extension
      }
      this.modifyScene(this.formValidate.id, formValidate, 'changeBlindPlay')
    },
    changeRunVmNum() {
      this.$refs.vmFormValidate.validate((valid) => {
        if (valid) {
          let extension = JSON.parse(this.formValidate.extension)
          extension.runningVmNum = this.vmFormValidate.runningVmNum
          this.formValidate.extension = JSON.stringify(extension)
          let formValidate = {
            extension: this.formValidate.extension
          }
          this.modifyScene(this.formValidate.id, formValidate, 'vmNum', extension.runningVmNum)
        }
      })
    },
    // 修改申请提示扣分的比率
    changeCtfDeduction() {
      this.$refs.ctfDeductionFormValidate.validate((valid) => {
        if (valid) {
          let extension = JSON.parse(this.formValidate.extension)
          extension.ctfDeduction = this.ctfDeductionFormValidate.ctfDeduction
          this.formValidate.extension = JSON.stringify(extension)
          let formValidate = {
            extension: this.formValidate.extension
          }
          this.ctfDeduction = this.ctfDeductionFormValidate.ctfDeduction
          this.modifyScene(this.formValidate.id, formValidate, 'changeCtfDeduction')
        }
      })
    },
    // 切换是否允许申请提示
    changeAllowApplicationPrompt() {
      let extension = JSON.parse(this.formValidate.extension)
      // isAllowApplicationPrompt为空时默认为1
      let isAllowApplicationPrompt = extension.isAllowApplicationPrompt
      isAllowApplicationPrompt = isAllowApplicationPrompt === 0 ? 1 : 0
      // 取反
      extension.isAllowApplicationPrompt = isAllowApplicationPrompt
      this.isAllowApplicationPrompt = isAllowApplicationPrompt
      this.formValidate.extension = JSON.stringify(extension)
      let formValidate = {
        extension: this.formValidate.extension
      }
      this.modifyScene(this.formValidate.id, formValidate, 'changeAllowApplicationPrompt')
    },
    changeConfigMode() {
      let extension = JSON.parse(this.formValidate.extension)
      let configMode = extension.configMode
      configMode = configMode !== 2 ? 2 : 1
      extension.configMode = configMode
      this.$set(this.extension, 'configMode', configMode)
      this.formValidate.extension = JSON.stringify(extension)
      let formValidate = {
        extension: this.formValidate.extension
      }
      this.modifyScene(this.formValidate.id, formValidate, 'changeConfigMode')
    },
    changEndClearConfig() {
      let extension = JSON.stringify({
        ...JSON.parse(this.drillDetail.extension),
        ...JSON.parse(this.formValidate.extension),
        endClearConfig: this.endClearConfig ? 0 : 1
      })
      let formValidate = { extension }
      this.modifyScene(this.formValidate.id, formValidate, 'changeEndClearConfig').then(() => {
        this.drillDetail.extension = extension
      })
    },
    // 切换是否允许提交报告
    changeReportSubmit() {
      let extension = JSON.parse(this.formValidate.extension)
      // isAllowApplicationPrompt为空时默认为1
      let isReportSubmit = extension.isReportSubmit
      isReportSubmit = isReportSubmit === 0 ? 1 : 0
      // 取反
      extension.isReportSubmit = isReportSubmit
      this.isReportSubmit = isReportSubmit
      this.formValidate.extension = JSON.stringify(extension)
      let formValidate = {
        extension: this.formValidate.extension
      }
      this.modifyScene(this.formValidate.id, formValidate, 'changeReportSubmit')
    },
    getCtfFlowConfigList() {
      let _this = this
      let params = {}
      params.page = _this.currentPage || 1
      params.rows = _this.pageSize || 10
      params.contestId = _this.$route.query.id
      params.projectId = _this.$route.query.prjid
      if (_this.checkStationSearchName) {
        params.teamName = _this.checkStationSearchName
      }
      ctfFlowConfig(params).then((data) => {
        if (data.code == 1) {
          _this.flowConfigDataList = data.data.items
          _this.flowConfigTotal = data.data.total
          if (this.flowConfigDataList.length <= 0) {
            _this.flowLength = false
            //如果没有流量配置，则自动导入，存入缓存
            this.autoInputFlowConfig()
            this.setFlowRedis()
          } else {
            _this.flowLength = true
            clearTimeout(_this.flowTimeout)
          }
        } else {
          _this.$Message.error(data.message)
        }
      })
    },
    autoInputFlowConfig() {
      let params = {}
      let _this = this
      newSaveFlowDataByPrj(_this.$route.query.id).then((data) => {
        if (data.code == 1) {
          if (data.code == 1) {
            //_this.$Message.info('保存成功');
            _this.flowTimeout = setTimeout(() => {
              _this.getCtfFlowConfigList()
            }, 3000)
          } else {
            _this.$Message.error(data.message)
          }
        }
      })
    },
    setFlowRedis() {
      let _this = this
      let params = {}
      setCtfFlowRedis(params).then((data) => {
        if (data.code == 1) {
          //_this.$Message.info('流量redis缓存设置成功')
        } else {
          _this.$Message.error(data.message)
        }
      })
    },
    getProjectInfo() {
      if (!this.$route.query.prjid) {
        return
      }
      return new Promise((resolve) => {
        this.disabledDestroy = false
        getstatusbyprjid(this.$route.query.prjid)
          .then((data) => {
            if (data.code == 1) {
              this.projectInfo = data.attribute.project
              this.attribute = data.attribute
              if (
                this.projectInfo.status == 0 ||
                this.projectInfo.status == 10 ||
                this.projectInfo.status == 14
              ) {
                clearInterval(this.timeoutP)
              }
            } else if (data.code == -2) {
              this.projectInfo.statusCHName = '工程不存在'
              this.disabledDestroy = true
            } else {
              this.$Message.error(data.message)
            }
          })
          .finally(() => {
            resolve()
          })
      })
    },
    getDrillDetail(needChangeStep, needServiceTime, setParams) {
      //是否需要切换步骤,是否需要服务时间请求
      return new Promise((resolve, reject) => {
        getSceneInfo(this.drillId).then((data) => {
          let startTimeChange = false
          let endTimeChange = false
          if (data.data.startTime != this.drillDetail.startTime) {
            startTimeChange = true
          }
          if (data.data.endTime != this.drillDetail.endTime) {
            endTimeChange = true
          }
          this.drillDetail = data.data

          if (JSON.parse(this.drillDetail.extension).isScheme) {
            // 判断是否是黄方下发的任务
            this.isScheme = JSON.parse(this.drillDetail.extension).isScheme
          }

          if (JSON.parse(this.drillDetail.extension).isDistributed) {
            this.isDistributed = JSON.parse(this.drillDetail.extension).isDistributed
          }
          if (JSON.parse(this.drillDetail.extension).isMainRange) {
            this.isMainRange = JSON.parse(this.drillDetail.extension).isMainRange
            // console.log(this.drillDetail,'getDrillDetailgetDrillDetailgetDrillDetail');
          }
          this.destoryTime = new Date(this.drillDetail.endTime).getTime() + 24 * 60 * 60 * 1000
          if (setParams == 'setEndDate') {
            this.formValidate.endDate = data.data.endTime
          }
          this.changeEndDate()
          let extensionObj
          try {
            extensionObj = JSON.parse(this.formValidate.extension)
          } catch (e) {
            extensionObj = {}
          }
          this.formValidate = Object.assign(this.formValidate, data.data)
          this.onlineMode = (data.data.extension && JSON.parse(data.data.extension).onlineMode) || 0
          this.extension = (data.data.extension && JSON.parse(data.data.extension)) || {}
          this.isExtraCredit = extensionObj.isExtraCredit || 0
          this.isBlindPlay =
            (data.data.extension && JSON.parse(data.data.extension).isBlindPlay) || 0
          this.touchType = (data.data.extension && JSON.parse(data.data.extension).touchType) || 1
          let isAllowApplicationPrompt = 1
          let basicDeduction = 10
          let ctfDeduction = 20
          let isReportSubmit = 1
          if (data.data.extension) {
            let extension = JSON.parse(data.data.extension)
            if (extension.isAllowApplicationPrompt !== undefined) {
              isAllowApplicationPrompt = extension.isAllowApplicationPrompt
            }
            if (extension.isReportSubmit !== undefined) {
              isReportSubmit = extension.isReportSubmit
            }
            if (extension.ctfDeduction !== undefined) {
              ctfDeduction = extension.ctfDeduction
            }
            if (extension.basicDeduction !== undefined) {
              basicDeduction = extension.basicDeduction
            }
          }
          this.isAllowApplicationPrompt = isAllowApplicationPrompt
          this.basicDeduction = basicDeduction
          this.isReportSubmit = isReportSubmit
          this.ctfDeduction = ctfDeduction
          if (this.isExtraCredit) {
            this.formValidate.ExtraCreditValue1 = extensionObj.ExtraCreditValue1 || 6
            this.formValidate.ExtraCreditValue2 = extensionObj.ExtraCreditValue2 || 4
            this.formValidate.ExtraCreditValue3 = extensionObj.ExtraCreditValue3 || 2
            this.formValidate.ExtraCredit1 = extensionObj.ExtraCredit1 || 1
            this.formValidate.ExtraCredit2 = extensionObj.ExtraCredit2 || 1
            this.formValidate.ExtraCredit3 = extensionObj.ExtraCredit3 || 1
          }
          this.formValidate.Dates = [this.formValidate.startTime, this.formValidate.endTime]
          if (this.drillDetail.progress == 0 || this.drillDetail.progress == 1) {
            if (needChangeStep) {
              this.toPreCompeManage()
            }
            if (needServiceTime || startTimeChange) {
              if (this.timeout) {
                clearTimeout(this.timeout)
              }
              this.getServeTime(new Date(this.drillDetail.startTime).getTime())
            }
            this.drillStatus = 1
            this.startContestStatus = false
            this.stopContestStatus = true
          } else if (
            this.drillDetail.progress == 2 ||
            this.drillDetail.progress == 3 ||
            this.drillDetail.progress == 5
          ) {
            if (needChangeStep) {
              this.toCompeingManage()
            }
            if (needServiceTime || endTimeChange) {
              if (this.timeout) {
                clearTimeout(this.timeout)
              }
              this.getServeTime(new Date(this.drillDetail.endTime).getTime())
            }
            this.drillStatus = 2
            this.startContestStatus = true
            this.stopContestStatus = false
          } else if (this.drillDetail.progress == 4) {
            if (needChangeStep) {
              this.toCompeedManage()
            }
            if (needServiceTime || endTimeChange) {
              if (this.timeout) {
                clearTimeout(this.timeout)
              }
              this.getServeTime(new Date(this.drillDetail.endTime).getTime())
            }
            this.drillStatus = 3
            this.startContestStatus = true
            this.stopContestStatus = true
          }
          resolve()
        })
      })
    },
    handleReset(name) {
      setTimeout(() => {
        this.$refs[name].resetFields()
        this.iconSrc = ''
        this.formValidate.iconPath = ''
      }, 200)
    },
    cancelLoading(modal) {
      modal.loading = false
      setTimeout(() => {
        modal.loading = true
      })
    },
    // showModal(){
    // 	this.sceneModal.show = true;
    // 	this.sceneModal.type = "2";
    // 	this.getDrillDetail();
    // },
    showModal(title, prop, saveFun, labelWidth) {
      this.sceneModal.title = title
      this.sceneModal.prop = prop
      this.sceneModal.labelWidth = labelWidth
      this.sceneModal.ok = saveFun
      this.sceneModal.show = true
      this.sceneModal.type = '2'
      this.getDrillDetail().then((data) => {
        this.formValidate = Object.assign(this.formValidate, this.drillDetail)
        this.$set(this.formValidate, 'Dates', [
          this.drillDetail.startTime,
          this.drillDetail.endTime
        ])
        let extension = parseJson(this.drillDetail.extension)
        this.formValidate.submitTime = extension.submitTime || 1
        this.formValidate.submitCount = extension.submitCount || 1
      })
    },
    handleSceneModalOk() {
      this.$refs.timeFormValidate
        .validate((valid) => {
          if (valid) {
            this.sceneModal.ok('timeFormValidate')
          } else {
            this.cancelLoading(this.sceneModal)
          }
        })
        .catch(() => {
          this.cancelLoading(this.sceneModal)
        })
    },
    modifyExtension() {
      let extension = JSON.parse(this.formValidate.extension)
      this.sceneModal.prop.forEach((item) => {
        extension[item] = this.formValidate[item]
      })
      let formValidate = { extension: JSON.stringify(extension) }
      this.modifyScene(this.formValidate.id, formValidate, this.sceneModal.prop.join(','))
    },
    saveScene(name) {
      this.$refs[name].validate((valid) => {
        if (valid) {
          let data = JSON.parse(JSON.stringify(this.formValidate))
          if (new Date(data.startTime).getTime() > new Date(data.endTime).getTime()) {
            this.$Message.error('表单输入有误，开始时间不能大于结束时间!')
            this.cancelLoading(this.sceneModal)
            return
          }
          if (
            new Date(data.endTime).getTime() - new Date(data.startTime).getTime() <
            60 * 60 * 1000
          ) {
            this.$Message.error('表单输入有误，起止时间最小间隔一个小时!')
            this.cancelLoading(this.sceneModal)
            return
          }
          delete data.Dates
          this.vmFormValidate.showNum = 0
          // 是否是修改虚拟机开始数量的操作
          let isModifyVmNum = name === 'vmFormValidate'
          let type = isModifyVmNum ? 'vmNum' : 'restart'
          // 修改可开启虚拟机的数量
          if (isModifyVmNum) {
            let extension
            try {
              extension = JSON.parse(data.extension)
            } catch (e) {
              extension = {}
            }
            extension.runningVmNum = this.vmFormValidate.runningVmNum
            data.extension = JSON.stringify(extension)
          }
          this.modifyScene(data.id, data, type, this.vmFormValidate.runningVmNum)
        } else {
          this.$Message.error('表单输入有误，请查看页面信息后重新输入!')
          this.cancelLoading(this.sceneModal)
        }
      })
    },
    saveSceneDelayTime(name) {
      this.$refs[name].validate((valid) => {
        if (valid) {
          let data = JSON.parse(JSON.stringify(this.formValidate))
          //	            let reg = new RegExp("((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\s([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$");
          //	            if(!reg.test(data.startTime) || !reg.test(data.endTime)){
          //	            	this.cancelLoading(this.sceneModal);
          //	            	this.$Message.error('时间格式错误');
          //	      			return;
          //	            }
          delete data.Dates
          data.endTime = data.endDate
          delete data.endDate
          this.modifyScene(data.id, data, 'delay')
        } else {
          this.$Message.error('表单输入有误，请查看页面信息后重新输入!')
          this.cancelLoading(this.sceneDelayModal)
        }
      })
    },
    saveSceneExtraCredit(name) {
      this.$refs[name].validate((valid) => {
        if (valid) {
          let extension = JSON.parse(this.formValidate.extension)
          if (this.onlineMode == 0 && this.isExtraCredit) {
            extension.ExtraCreditValue1 = this.incentivesObj.ExtraCreditValue1
            extension.ExtraCreditValue2 = this.incentivesObj.ExtraCreditValue2
            extension.ExtraCreditValue3 = this.incentivesObj.ExtraCreditValue3
            extension.ExtraCredit1 = this.incentivesObj.ExtraCredit1
            extension.ExtraCredit2 = this.incentivesObj.ExtraCredit2
            extension.ExtraCredit3 = this.incentivesObj.ExtraCredit3
          }
          let params = {
            extension: JSON.stringify(extension)
          }
          this.modifyScene(this.formValidate.id, params, 'ExtraCredit')
        } else {
          this.$Message.error('表单输入有误，请查看页面信息后重新输入!')
          this.cancelLoading(this.sceneExtraCreditModal)
        }
      })
    },
    modifyScene(id, data, type, showNum) {
      return new Promise((resolve, reject) => {
        modifyScene(id, data)
          .then((data) => {
            if (data.code == 1) {
              //this.$Message.info('修改演练场景成功');
              this.sceneModal.show = false
              this.sceneDelayModal.show = false
              this.sceneExtraCreditModal.show = false
              this.ctfDeductionFormValidate.show = false
              if (type == 'delay') {
                setTimeout(() => {
                  this.getDrillDetail(false, true)
                }, 2000)
              } else {
                if (type == 'restart') {
                  this.$Message.info('重新开始比赛成功')
                } else if (type === 'vmNum') {
                  this.$Message.info('修改参赛选手可同时开机数量成功')
                  this.vmFormValidate.runningVmModal = false
                  this.vmFormValidate.showNum = showNum
                  // 可开启的虚拟机数量已修改，需要发送公告
                  if (this.accessGroupList.length) {
                    // 比赛包含用户，开始为用户发送公告
                    let params = {
                      sceneId: this.$route.query.id,
                      noticeSceneDto: {
                        accessGroups: this.accessGroupList,
                        content: `参赛选手可同时开机数量修改为${showNum}台`,
                        id: '',
                        title: `4/${showNum}`,
                        type: 1 // 切换盲打模式，发送的是实物公告
                      }
                    }
                    sendToSence(params)
                      .then((data) => {
                        if (data.code == 1) {
                        } else {
                          this.$Message.warning(data.message)
                        }
                        this.disabledSend = false
                      })
                      .catch(() => {
                        this.$Message.error('公告发送失败')
                        this.disabledSend = false
                      })
                  }
                } else if (type == 'ExtraCredit') {
                  this.$Message.info('修改激励分配置成功')
                  let {
                    ExtraCredit1,
                    ExtraCreditValue1,
                    ExtraCredit2,
                    ExtraCreditValue2,
                    ExtraCredit3,
                    ExtraCreditValue3
                  } = this.incentivesObj
                  this.$set(this.formValidate, 'ExtraCredit1', ExtraCredit1)
                  this.$set(this.formValidate, 'ExtraCreditValue1', ExtraCreditValue1)
                  this.$set(this.formValidate, 'ExtraCredit2', ExtraCredit2)
                  this.$set(this.formValidate, 'ExtraCreditValue2', ExtraCreditValue2)
                  this.$set(this.formValidate, 'ExtraCredit3', ExtraCredit3)
                  this.$set(this.formValidate, 'ExtraCreditValue3', ExtraCreditValue3)
                  return
                } else if (type === 'changeBlindPlay') {
                  let messageText
                  if (this.isBlindPlay === 1) {
                    messageText = '开启盲打模式'
                  } else {
                    messageText = '关闭盲打模式'
                  }
                  this.$Message.info(messageText)
                  // 切换盲打模式，发送公告
                  if (this.accessGroupList.length) {
                    // 比赛包含用户，开始为用户发送公告
                    let params = {
                      sceneId: this.$route.query.id,
                      noticeSceneDto: {
                        accessGroups: this.accessGroupList,
                        content: messageText,
                        id: '',
                        title: `3/${this.isBlindPlay}`,
                        type: 1 // 切换盲打模式，发送的是实物公告
                      }
                    }
                    sendToSence(params)
                      .then((data) => {
                        if (data.code == 1) {
                        } else {
                          this.$Message.warning(data.message)
                        }
                        this.disabledSend = false
                      })
                      .catch(() => {
                        this.$Message.error('公告发送失败')
                        this.disabledSend = false
                      })
                  }
                } else if (type === 'changeReportSubmit') {
                  let messageText
                  if (this.isReportSubmit === 1) {
                    messageText = '报告提交通道已开启'
                  } else {
                    messageText = '报告提交通道已关闭'
                  }
                  this.$Message.info(messageText)
                  // 切换是否允许申请，发送公告
                  if (this.accessGroupList.length) {
                    // 比赛包含用户，开始为用户发送公告
                    let params = {
                      sceneId: this.$route.query.id,
                      noticeSceneDto: {
                        accessGroups: this.accessGroupList,
                        content: messageText,
                        id: '',
                        title: `6/${this.isReportSubmit}`,
                        type: 1 // 切换盲打模式，发送的是实物公告
                      }
                    }
                    sendToSence(params)
                      .then((data) => {
                        if (data.code == 1) {
                        } else {
                          this.$Message.warning(data.message)
                        }
                        this.disabledSend = false
                      })
                      .catch(() => {
                        this.$Message.error('公告发送失败')
                        this.disabledSend = false
                      })
                  }
                } else if (type === 'changeAllowApplicationPrompt') {
                  let messageText
                  if (this.isAllowApplicationPrompt === 1) {
                    messageText = '允许申请提示'
                  } else {
                    messageText = '不允许申请提示'
                  }
                  this.$Message.info(messageText)
                  // 切换是否允许申请，发送公告
                  if (this.accessGroupList.length) {
                    // 比赛包含用户，开始为用户发送公告
                    let params = {
                      sceneId: this.$route.query.id,
                      noticeSceneDto: {
                        accessGroups: this.accessGroupList,
                        content: messageText,
                        id: '',
                        title: `5/${this.isAllowApplicationPrompt}`,
                        type: 1 // 切换盲打模式，发送的是实物公告
                      }
                    }
                    sendToSence(params)
                      .then((data) => {
                        if (data.code == 1) {
                        } else {
                          this.$Message.warning(data.message)
                        }
                        this.disabledSend = false
                      })
                      .catch(() => {
                        this.$Message.error('公告发送失败')
                        this.disabledSend = false
                      })
                  }
                } else if (type === 'changeCtfDeduction') {
                  if (this.accessGroupList.length) {
                    // 比赛包含用户，开始为用户发送公告
                    let params = {
                      sceneId: this.$route.query.id,
                      noticeSceneDto: {
                        accessGroups: this.accessGroupList,
                        content: `申请提示的扣分比例已修改为${this.ctfDeduction}%`,
                        id: '',
                        title: `7/${this.ctfDeduction}`,
                        type: 1 // 修改扣分比例，发送的是实物公告
                      }
                    }
                    this.$Message.info(`申请提示的扣分比例已修改为${this.ctfDeduction}%`)
                    sendToSence(params)
                      .then((data) => {
                        if (data.code == 1) {
                        } else {
                          this.$Message.warning(data.message)
                        }
                        this.disabledSend = false
                      })
                      .catch(() => {
                        this.$Message.error('公告发送失败')
                        this.disabledSend = false
                      })
                  }
                } else if (type === 'changeConfigMode') {
                  this.$Message.info('模式切换成功')
                } else if (type.indexOf('submitTime') != -1) {
                  this.$Message.info('修改报告提交频率成功')
                  // this.getDrillDetail();
                } else if (type === 'changeEndClearConfig') {
                  this.$Message.info('切换结束后是否销毁环境成功')
                }
                setTimeout(() => {
                  this.getDrillDetail()
                }, 2000)
              }
              resolve()
            } else {
              this.cancelLoading(this.sceneModal)
              this.cancelLoading(this.sceneDelayModal)
              this.cancelLoading(this.sceneExtraCreditModal)
              this.$Message.warning(data.message)
              reject()
            }
          })
          .catch((error) => {
            this.cancelLoading(this.sceneModal)
            this.cancelLoading(this.sceneDelayModal)
            this.$Message.error(error)
            reject()
          })
      })
    },
    // 查询当前比赛用户组信息
    getAccessGroupList() {
      let params = {
        pageIndex: 1,
        pageSize: 2147483647,
        testId: this.$route.query.id
      }
      getaccessgrouplist(params).then(({ code, data, message }) => {
        if (code == 1) {
          this.accessGroupList = data.items.map((item) => {
            return Object.assign(item, {
              groupId: item.id,
              userIds: item.userList.map((childItem) => {
                return childItem.userId
              })
            })
          })
        } else if (code == -2) {
          this.accessGroupList = []
        } else {
          this.$Message.warning(message)
        }
      })
    },
    timeChange(timeArr) {
      if (timeArr.length > 0) {
        this.formValidate.startTime = timeArr[0] ? timeArr[0] + ':00' : ''
        this.formValidate.endTime = timeArr[1] ? timeArr[1] + ':00' : ''
      }
    },
    changePreTab(name) {
      this.preDefault = name
      if (name == 'accessUser') {
      }
    },
    changeMidTab(name) {
      this.midDefault = name
      if (name == 'accessUser') {
      }
    },
    changeEndTab(name) {
      this.endDefault = name
      if (name == 'accessUser') {
      }
    },
    initPane() {
      this.preDefault = 'accessGroup'
      this.midDefault = 'accessGroup'
      this.endDefault = 'teamRankStatic'
    },
    toPreCompeManage() {
      //演练前设置页面
      this.preDefault = 'accessGroup'
      this.midDefault = ''
      this.endDefault = ''
      this.currentIndex = 0
      setTimeout(() => {
        this.preCompeManagePanelShow = true
        this.compeingManagePanelShow = false
        this.compeedManagePanelShow = false
      })
    },
    toCompeingManage() {
      //演练中
      if (this.drillDetail.progress == 0 || this.drillDetail.progress == 1) {
        return
      }
      this.preDefault = ''
      this.midDefault = 'accessGroup'
      this.endDefault = ''
      this.currentIndex = 1
      setTimeout(() => {
        this.preCompeManagePanelShow = false
        this.compeingManagePanelShow = true
        this.compeedManagePanelShow = false
      })
    },
    toCompeedManage() {
      //演练后
      if (this.drillDetail.progress != 4) {
        return
      }
      this.preDefault = ''
      this.midDefault = ''
      this.endDefault = 'teamRankStatic'
      this.currentIndex = 2
      setTimeout(() => {
        this.preCompeManagePanelShow = false
        this.compeingManagePanelShow = false
        this.compeedManagePanelShow = true
      })
    },
    // 恢复暂停的比赛
    async restoreCompetition() {
      //加一个提示-bug15794
      this.tipModal.show = true
      this.tipModal.content = '正在恢复比赛...请稍后!!'
      await this.restoreCompetition_minixs(this.drillId) //方法在recoverTime混入中
      this.tipModal.show = false
    },
    // 暂停比赛
    pauseCompetition() {
      //加一个提示-bug15794
      this.tipModal.show = true
      this.tipModal.content = '正在暂停比赛...请稍后!!'
      this.changeCompetitionStatus(5, '暂停')
    },
    changeCompetitionStatus(status, op) {
      updateSceneProgress(this.drillId, status)
        .then((data) => {
          if (data.code == 1) {
            this.$Message.info(`${op}成功`)
            this.tipModal.show = false
            this.getDrillDetail()
            if (status == 2) {
              //this.setSceneCycle();
            }
            if (status == 4 && this.touchType === 2) {
              // 新的盲打模式结束时，需要调用接口计算分数
              calculateScore(this.$route.query.id)
                .then(({ code, message }) => {
                  if (code !== 1) {
                    this.$Message.warning(message)
                  }
                })
                .catch(() => {
                  this.$Message.error('自动计算得分异常')
                })
            }
          } else {
            this.$Message.error(data.message)
            this.tipModal.show = false
          }
        })
        .catch((error) => {
          this.$Message.error(error.message)
          this.tipModal.show = false
        })
    },
    validateStart() {
      this.canStartCompete(this.drillDetail.type).then((data) => {
        this.$Message.info('校验完成')
      })
    },
    getTaskList(status) {
      if (status == 2) {
        this.canStartCompete(this.drillDetail.type).then((data) => {
          if (!data) {
            this.$Message.warning('请检查团队成员配置及题目分配是否完成')
            return
          } else {
            this.opTaskListNew(status)
          }
        })
        this.tipModal.content = '正在开始比赛...请稍后!!'
      } else {
        this.tipModal.content = '正在停止比赛...请稍后!!'
        this.opTaskListNew(status)
      }
    },
    // 新版操作，一键启动所有任务
    opTaskListNew(status) {
      this.tipModal.show = true
      let str
      if (status == 2) {
        //开始
        str = 'start'
      } else {
        str = 'stop'
      }
      let params = {
        sceneId: this.$route.query.id,
        taskMode: 'preset',
        op: str
      }
      this.changeCompetitionStatus(status, status == 2 ? '开始' : '结束')
    },
    // 老版操作，分批启动指定任务
    opTaskList(status) {
      this.tipModal.show = true
      let opTask = []
      //flag单次提交任务
      let params1 = {
        testId: this.$route.query.id,
        page: 1,
        rows: 10000,
        taskType: 'once_submit_flag',
        taskMode: 'preset'
      }
      let str, condition
      if (status == 2) {
        //开始
        str = 'start'
      } else {
        str = 'stop'
      }
      let p1 = new Promise((resolve, reject) => {
        getTaskList(params1).then((data) => {
          if (data.code == 1) {
            let taskList = data.data.items
            taskList.forEach((task) => {
              if (status == 2) {
                //if(task.status == 'initialized'){
                opTask.push({
                  operation: str,
                  taskId: task.id
                })
                //}
              } else if (status == 4) {
                if (task.status == 'running') {
                  opTask.push({
                    operation: str,
                    taskId: task.id
                  })
                }
              }
            })
            resolve()
          }
        })
      })
      //flag配置-外部
      let params2 = {
        testId: this.$route.query.id,
        page: 1,
        rows: 10000,
        taskType: 'once_configure_flag',
        taskMode: 'preset'
      }
      let p2 = new Promise((resolve, reject) => {
        getTaskList(params2).then((data) => {
          if (data.code == 1) {
            let taskList = data.data.items
            taskList.forEach((task) => {
              if (status == 2) {
                //if(task.status == 'initialized'){
                opTask.push({
                  operation: str,
                  taskId: task.id
                })
                //}
              } else if (status == 4) {
                if (task.status == 'running') {
                  opTask.push({
                    operation: str,
                    taskId: task.id
                  })
                }
              }
            })
            resolve()
          }
        })
      })
      //checker
      let params3 = {
        testId: this.$route.query.id,
        page: 1,
        rows: 10000,
        taskType: 'checker',
        taskMode: 'preset'
      }
      let p3 = new Promise((resolve, reject) => {
        getTaskList(params3).then((data) => {
          if (data.code == 1) {
            let taskList = data.data.items
            taskList.forEach((task) => {
              if (status == 2) {
                if (task.status == 'initialized' || task.status == 'completed') {
                  opTask.push({
                    operation: str,
                    taskId: task.id
                  })
                }
              } else if (status == 4) {
                if (task.status == 'running') {
                  opTask.push({
                    operation: str,
                    taskId: task.id
                  })
                }
              }
            })
            resolve()
          }
        })
      })
      //	    	//动态Flag配置
      //	    	let params4 = {
      //	    		"testId":this.$route.query.id,
      //              "page":1,
      //              "rows":10000,
      //              "taskType":'loop_configure_flag',
      //              "taskMode":"preset"
      //	    	}
      //	    	let p4 = new Promise((resolve,reject) => {
      //		    	getTaskList(params4).then(data => {
      //		    		if(data.code == 1){
      //		    			let taskList = data.data.items;
      //		    			taskList.forEach(task => {
      //		    				if(status == 2){
      //		    					if(task.status == 'initialized' || task.status == "completed"){
      //			    					opTask.push({
      //			    						"operation": str,
      //		    							"taskId": task.id
      //			    					})
      //			    				}
      //		    				}else if(status == 4){
      //		    					if(task.status == 'running'){
      //			    					opTask.push({
      //			    						"operation": str,
      //		    							"taskId": task.id
      //			    					})
      //			    				}
      //		    				}
      //		    			})
      //		    			resolve();
      //		    		}
      //		    	})
      //	    	})
      //	    	//数据通道
      //	    	let params5 = {
      //	    		"testId":this.$route.query.id,
      //              "page":1,
      //              "rows":10000,
      //              "taskType":'tunnel',
      //              "taskMode":"preset"
      //	    	}
      //	    	let p5 = new Promise((resolve,reject) => {
      //		    	getTaskList(params5).then(data => {
      //		    		if(data.code == 1){
      //		    			let taskList = data.data.items;
      //		    			taskList.forEach(task => {
      //		    				if(status == 2){
      //		    					if(task.status == 'initialized' || task.status == "completed"){
      //			    					opTask.push({
      //			    						"operation": str,
      //		    							"taskId": task.id
      //			    					})
      //			    				}
      //		    				}else if(status == 4){
      //		    					if(task.status == 'running'){
      //			    					opTask.push({
      //			    						"operation": str,
      //		    							"taskId": task.id
      //			    					})
      //			    				}
      //		    				}
      //		    			})
      //		    			resolve();
      //		    		}
      //		    	})
      //	    	})
      Promise.all([p1, p2, p3]).then((data) => {
        this.activeTask(opTask).then((data) => {
          this.changeCompetitionStatus(status, status == 2 ? '开始' : '结束')
        })
      })
    },
    activeTask(tasks) {
      let $this = this
      //          if(active=="开始"){
      //              active = "start"
      //          }else if(active=="停止"){
      //              active = "stop"
      //          }
      //          axios({
      //              url:this.GLOBAL._projPath_process +"custom/tasks/"+taskId+'/execute?operation='+active,
      //              method:'post'
      //          }).
      return new Promise((resolve, reject) => {
        if (tasks.length == 0) {
          resolve()
        }
        batchActiveTask(tasks).then((response) => {
          let activeType
          if (response.code == 1) {
            if (response.data.length > 0 && response.data.some((task) => task.code == 0)) {
              response.data.forEach((task) => {
                if (task.code == 0) {
                  $this.$Message.warning(task.message)
                }
              })
            } else {
            }
            resolve()
          } else {
            $this.$Message.error(response.message)
          }
        })
      })
    },
    //添加场景周期
    setSceneCycle() {
      setSceneCycle(this.drillId).then((data) => {
        if (data.code == 1) {
        } else {
          this.$Message.warning(data.message)
        }
      })
    },
    //释放资源
    clearProject() {
      this.disabledDestroy = true
      clearProject(this.$route.query.prjid)
        .then((data) => {
          if (data.code == 1 || data.code == 3) {
            this.$Message.info('环境清空中...')
            clearInterval(this.timeoutP)
            this.timeoutP = setInterval((data) => {
              this.getProjectInfo()
            }, 3000)
          } else {
            this.$Message.warning(data.message)
          }
          this.disabledDestroy = false
        })
        .catch((error) => {
          this.disabledDestroy = false
        })
    },
    showVisualization() {
      // 修改后的跳转路径
      let oToken = localStorage.getItem('token')
      window.open(
        `${window.location.origin}/ctfPage/ctfCompete.html?contestId=${this.$route.query.id}&token=${oToken}&prjid=${this.$route.query.prjid}`,
        '_black'
      )
      //线下测试
      // window.open(
      //        `http://localhost:8080/ctfCompete4-car.html?contestId=${this.$route.query.id}&token=${oToken}&projectId=${this.$route.query.prjid}`,
      //        '_black')
    },
    showVisualizationAnswer() {
      // 修改后的跳转路径
      let oToken = localStorage.getItem('token')
      localStorage.setItem('oToken', oToken)
      localStorage.setItem('contestId', this.$route.query.id)
      window.open(`${window.location.origin}/ctfPage/answerSheet.html?lang=zh`, '_black')
    },
    hideModal() {
      this.boardModal = false
    },
    destoryProject() {
      return (
        this.disabledDestroy ||
        !this.startContestStatus ||
        !this.stopContestStatus ||
        !(this.projectInfo.status == 3 || this.projectInfo.status == 14) ||
        (JSON.parse(this.drillDetail.extension).isDistributed == 1 &&
          JSON.parse(this.drillDetail.extension).isMainRange != 1)
      )
    },
    returnPage() {
      this.$router.push(this.backObj)
    },
    gotoReportPage() {
      const { href } = this.$router.resolve({
        name: 'ctfReport',
        query: {
          id: this.$route.query.id,
          type: 2
        }
      })
      window.open(href, '_blank')
    },
    resetEnviron() {
      this.tipModal.show = true
      this.tipModal.content = '正在重置环境...请稍后!!'
      batchOpVm(this.projectId, 'rebuild')
        .then((data) => {
          if (data.code == 1) {
            this.$Message.info('操作成功')
            this.batchOpVmLog()
          } else {
            this.$Message.error(data.message)
          }
          this.tipModal.show = false
        })
        .catch((error) => {
          this.$Message.error('环境重置失败')
          this.tipModal.show = false
        })
    },
    batchOpVmLog(isFirst) {
      batchOpVmLog(this.queryOpLogInfo)
        .then((data) => {
          if (data.code == 1) {
            if (data.data.items.length > 0) {
              //重置过
              let id = data.data.items[0].id
              this.batchOpVmLogDetail(id, isFirst)
            } else {
              //未重置
              this.resetStatus = 0
            }
          } else {
            this.$Message.error(data.messsage)
          }
        })
        .catch((error) => {
          this.$Message.error('查询重置详情失败')
        })
    },
    batchOpVmLogDetail(id, isFirst) {
      batchOpVmLogOnce(id)
        .then((data) => {
          if (data.code == 1) {
            this.resetInfo = data.data
            this.resetInfo.finished = this.resetInfo.finished || 0
            this.resetProgress = parseInt((this.resetInfo.finished / this.resetInfo.total) * 100)
            if (this.resetInfo.finished == this.resetInfo.total) {
              this.resetStatus = 2 // 重置完成
              if (this.resetInfo.msgs.filter((item) => item.errMsg).length > 0) {
                this.resetFail = true
                if (!isFirst) {
                  this.$Message.error('重置失败')
                }
              } else {
                this.resetFail = false
                if (!isFirst) {
                  this.$Message.info('重置成功')
                }
              }
            } else if (this.resetInfo.finished < this.resetInfo.total) {
              this.resetStatus = 1 //重置中
            }
            if (this.resetStatus != 2) {
              setTimeout(() => {
                this.batchOpVmLogDetail(id)
              }, 2000)
            }
          } else {
            this.$Message.error(data.messsage)
          }
        })
        .catch((error) => {
          this.$Message.error('查询重置详情失败')
        })
    },
    getResetDetail() {
      this.resetDetailModal.show = true
    },
    rebuildAllFailVm() {
      this.tipModal.show = true
      this.tipModal.content = '正在重置环境...请稍后!!'
      let proArr = this.resetInfo.msgs
        .filter((item) => item.errMsg)
        .map(async (vm) => {
          await this.rebuildVm(vm.id)
        })
      Promise.all(proArr)
        .then((data) => {
          this.tipModal.show = false
          this.$Message.info('重置完成')
        })
        .catch((error) => {
          this.$Message.info('重置失败')
        })
    },
    rebuildVm(id) {
      return new Promise((resolve, reject) => {
        rebuildVm(id)
          .then((data) => {
            if (data.code == 1) {
              resolve(data)
            } else {
              reject()
            }
          })
          .catch((error) => {
            reject()
            //this.$Message.error('重置【'+vm.name+'】失败');
          })
      })
    },
    showDelayModal() {
      this.sceneDelayModal.show = true
      this.getDrillDetail('', '', 'setEndDate')
    },
    changeEndDate(time) {
      if (time) {
        this.formValidate.endDate = time + ':00'
      }
    },
    showExtraCreditModal() {
      this.sceneExtraCreditModal.show = true
      let {
        ExtraCredit1,
        ExtraCreditValue1,
        ExtraCredit2,
        ExtraCreditValue2,
        ExtraCredit3,
        ExtraCreditValue3
      } = this.formValidate
      this.$set(this.incentivesObj, 'ExtraCredit1', ExtraCredit1)
      this.$set(this.incentivesObj, 'ExtraCreditValue1', ExtraCreditValue1)
      this.$set(this.incentivesObj, 'ExtraCredit2', ExtraCredit2)
      this.$set(this.incentivesObj, 'ExtraCreditValue2', ExtraCreditValue2)
      this.$set(this.incentivesObj, 'ExtraCredit3', ExtraCredit3)
      this.$set(this.incentivesObj, 'ExtraCreditValue3', ExtraCreditValue3)
    },
    clearSceneNoticeAndChat() {
      const msg = this.$Message.loading({
        content: '正在清空...',
        duration: 0,
        closable: true
      })
      let sceneId = this.$route.query.id
      clearSceneNoticeAndChat(sceneId)
        .then((data) => {
          setTimeout(msg, 1000)
          setTimeout(() => {
            if (data.code == 1) {
              this.$Message.info('清空成功')
              this.$refs['chatRoom'].clearChatMsg()
            } else {
              this.$Message.info('清空失败')
            }
          }, 1100)
        })
        .catch((error) => {
          setTimeout(msg, 1000)
          setTimeout(() => {
            this.$Message.info('清空失败')
          }, 1100)
        })
    },
    changePreDefault(val) {
      this.preDefault = val
    }
  },
  computed: {
    ...mapState('board', ['refreshTime']), //
    hasOwnDevice() {
      // 有自带实物接入设备
      return this.environInfo.pmInEnable
    },
    hsaProblemsystem() {
      // 有答题系统
      return this.deployMode !== 2
    },
    hasAccessMachine() {
      // 有虚拟接入设备
      return this.environInfo.vmInEnable
    },
    runningVmNum() {
      return this.extension.runningVmNum || 0
    },
    isPartialBuilding() {
      return this.extension.deploymentType
    },
    isWan() {
      // 网络模式是外网
      return this.extension.onLineType === 'wan'
    },
    isSupergroup() {
      return this.extension.isSupergroup === 1
    },
    isBasicScore() {
      return this.extension.isBasicScore === 1
    },
    deployMode() {
      return this.extension.deployMode || 2
    },
    wpUpMode() {
      return this.extension.wpUpMode
    },
    envType() {
      return this.extension.envType === 0 ? 0 : 1
    },
    submitTime() {
      return this.extension.submitTime || 1
    },
    submitCount() {
      return this.extension.submitCount || 1
    },
    vpn() {
      return this.extension.vpn || false
    },
    ipMode() {
      return this.extension.ipMode || ''
    },
    ctfOnlineType() {
      return this.extension.ctfOnlineType || ''
    },
    onlineTypeShow() {
      return this.vpn ? 'VPN' : this.ctfOnlineType === 'domain' ? '域名' : 'ip + 端口'
    },
    ctfVpn() {
      return this.onlineMode === 1 && this.vpn
    },
    disabledAllBtn() {
      if (
        this.projectInfo.status != 3 ||
        this.drillDetail.creator != this.USER_ID ||
        this.isWindowed ||
        this.configIsSuspend
      ) {
        return true
      }
      // return this.projectInfo.status != 3 || this.drillDetail.creator != this.USER_ID || this.isWindowed || this.configIsSuspend;
      if (JSON.parse(this.drillDetail.extension).isDistributed) {
        if (JSON.parse(this.drillDetail.extension).isMainRange != 1) {
          return true
        } else {
          return false
        }
      } else {
        return false
      }
    },
    notOwn() {
      return this.drillDetail.creator !== this.USER_ID
    },
    configMode() {
      return this.extension.configMode || 2
    },
    title() {
      //当前菜单显示名
      return this.$store.getters.pageTitle
    }
  }
}
</script>
<style scoped src="./detail.css"></style>
<style scoped>
.levelConfig {
  display: flex;
  margin-bottom: 10px;
  align-items: center;
}
.levelConfig /deep/ .levelConfig-label {
  float: left;
  text-align: center;
  background-color: rgb(56, 56, 211) !important;
  border-color: rgb(56, 56, 211) !important;
  color: #fff;
  border-radius: 4px 0 0 4px;
}
.levelConfig /deep/ .levelConfig-label-small {
  width: 50px;
}
.levelConfig /deep/ .levelConfig-label-long {
  width: 74px;
}
.levelConfig /deep/ .levelConfig-label + .ivu-input-number {
  border-radius: 0 4px 4px 0;
  margin-top: -1px;
}
.levelConfig /deep/ .ivu-input-group-prepend {
  background-color: rgb(56, 56, 211) !important;
  border-color: rgb(56, 56, 211) !important;
  color: #fff;
}
.levelConfig /deep/ .ivu-form-item {
  margin-bottom: 10px;
}
</style>
